在Grid.SetLeft和Grid.SetTop上注册回调

时间:2014-02-06 11:25:12

标签: wpf

我需要通知客户端组件网格中控件的位置变化。

如果有人调用Grid.SetLeft(control,x),是否有可能获得通知?

当然我可以实现自己的Left-Properties,它首先调用Grid.SetLeft然后调用回调,但是如果其他人以另一种方式移动Control,我就不会被告知。

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

如链接答案所述,您只需使用OverrideMetadata注册自己的回调即可。

我假设您使用的是Canvas,而不是Grid,因为Canvas是SetLeft的组件。

在下面的示例中,我向Canvas添加了两个组件,一个Button和一个TextBlock,并在单击它们时更改它们的位置。
然后我注册了三个覆盖,一个使用按钮作为类型,一个使用文本块,一个使用UIElement。尝试按原样运行应用程序,并注意UIElement如何不触发。删除两个第一行,Button和TextBlock的回调,并查看它现在如何使用UIElement回调。
您可以使用它来过滤掉需要收听的类型。

<Window x:Class="WpfApplication6.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Canvas>
            <Button Width="100" Height="30" Content="Click" Click="ButtonBase_OnClick" x:Name="btn"/>
            <TextBlock Text="Click" Width="100" Height="30" Canvas.Top="40" MouseDown="UIElement_OnMouseDown" x:Name="tb"/>
        </Canvas>
    </Grid>
</Window>

代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Canvas.LeftProperty.OverrideMetadata(typeof(Button), new FrameworkPropertyMetadata(ButtonCallback));
        Canvas.LeftProperty.OverrideMetadata(typeof(TextBlock), new FrameworkPropertyMetadata(TextBoxCallback));
        Canvas.LeftProperty.OverrideMetadata(typeof(UIElement), new FrameworkPropertyMetadata(UIElementCallback));
    }

    private void ButtonCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Console.WriteLine("Button changed position");
    }

    private void TextBoxCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Console.WriteLine("Textbox changed position");
    }

    private void UIElementCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Console.WriteLine("UI Element changed position");
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        Canvas.SetLeft(btn, 100);
    }

    private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
    {
        Canvas.SetLeft(tb, 100);
    }
}