简体   繁体   中英

SizeChanged not firing for elements on Canvas

I have a simple UWP app defined as follows:

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>

The problem is that SizeChanged never fires and Rectangle_SizeChanged never gets called when the size of Rectangle changes. Am i missing something or it's a bug in UWP? The below XAML with Canvas replaced with Grid works.

<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>

Canvas uses absolute positioning as its layout technique for its contained child elements. So SizeChanged event of the child will not trigger. It doesn't consider sizing or scaling. it depends on x,y coordinates. I am quoting exact lines from Microsoft document.

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

Because absolute positioning does not take into account the size of the app window, scaling, or other user-selected sizing, using a container element that adapts to different orientations and screen settings, such as Grid or StackPanel, is often a better choice than using Canvas.

You can read more about it in Layout Panels

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM