首页 > 解决方案 > SizeChanged 未触发 Canvas 上的元素

问题描述

我有一个简单的 UWP 应用程序,定义如下:

using System;
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace SizeChangedBug
{
  public sealed partial class MainPage : Page
  {
    public MainPage() {
      this.InitializeComponent();
      this.Rectangle.SizeChanged += Rectangle_SizeChanged;
    }

    private void Rectangle_SizeChanged(object sender, SizeChangedEventArgs e) {
      Debug.WriteLine("Rectangle_SizeChanged");
    }
  }
}
<Page
    x:Class="SizeChangedBug.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SizeChangedBug"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

  <Canvas>
    <Slider x:Name="Slider" Orientation="Vertical" Width="80" Height="300" Value="400" Minimum="0" Maximum="600" HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <Rectangle x:Name="Rectangle" Margin="200,200" Width="{Binding Value, ElementName=Slider}" Height="{Binding Value, ElementName=Slider}" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Top"/>
  </Canvas>
</Page>

问题是 SizeChanged 永远不会触发, Rectangle_SizeChanged 永远不会在 Rectangle 的大小发生变化时被调用。我错过了什么还是 UWP 中的错误?下面的 XAML 将 Canvas 替换为 Grid 工作。

<Page
    x:Class="SizeChangedBug.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SizeChangedBug"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

  <Grid>
    <Slider x:Name="Slider" Orientation="Vertical" Width="80" Height="300" Value="400" Minimum="0" Maximum="600" HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <Rectangle x:Name="Rectangle" Margin="200,200" Width="{Binding Value, ElementName=Slider}" Height="{Binding Value, ElementName=Slider}" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Top"/>
  </Grid>
</Page>

标签: c#uwpuwp-xaml

解决方案


Canvas 使用绝对定位作为其包含的子元素的布局技术。所以子的 SizeChanged 事件不会触发。它不考虑调整大小或缩放。它取决于 x,y 坐标。我引用了 Microsoft 文档中的确切内容。

https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.canvas#remarks

因为绝对定位不考虑应用程序窗口的大小、缩放或其他用户选择的大小,所以使用适应不同方向和屏幕设置的容器元素,例如 Grid 或 StackPanel,通常是比使用更好的选择帆布。

您可以在布局面板中了解更多信息


推荐阅读