在多个实例中使用依赖项属性

时间:2013-09-03 22:49:54

标签: c# wpf xaml dependency-properties

我基本上和这个人有同样的问题:Error: " 'Subjects' property was already registered by 'Period' " is raised when more than one control is placed on the form

我们之间的主要区别是我想订阅一个在xaml更改属性时可以访问本地实例的事件。

所以我有我的UserControl:

public partial class BoardSquare : UserControl
{
    public BoardSquare()
    {
        InitializeComponent();
        Location = new BoardLocation(Int32.MinValue, Int32.MinValue);

        XPositionProperty =
             DependencyProperty.Register("XPosition", typeof(int),
             typeof(BoardSquare), new PropertyMetadata(
                 new PropertyChangedCallback((value, args) => 
                 { 
                     Location.X = (int)args.NewValue;
                     resetBackgroundColorToPosition();
                 })));
        YPositionProperty=
            DependencyProperty.Register("YPosition", typeof(int),
            typeof(BoardSquare), new PropertyMetadata(
                new PropertyChangedCallback((value, args)=>
                {
                    Location.Y = (int)args.NewValue;
                    resetBackgroundColorToPosition();
                })));
    }

    private void resetBackgroundColorToPosition()
    {
        this.Background = (Brush)(new ColorEnumToBrushesConverter()).Convert(Location.GetSquareColor(), typeof(BlackWhiteColor), null, null);
    }

    public readonly DependencyProperty XPositionProperty;
    public readonly DependencyProperty YPositionProperty;

    public int XPosition
    {
        get
        {
            return (int)GetValue(XPositionProperty);
        }
        set
        {
            SetValue(XPositionProperty, value);
        }
    }

    public int YPosition 
    { 
        get
        {
            return (int)GetValue(YPositionProperty);
        }
        set
        {
            SetValue(YPositionProperty, value);
        }
    }

    public BoardLocation Location { get; set; }
}

这是我的XAML:

<local:BoardSquare Grid.Column="3" Grid.Row="0" XPosition="3" YPosition="0"/>
<local:BoardSquare Grid.Column="4" Grid.Row="0" XPosition="4" YPosition="0"/>

根据我的理解,解决方案是使XPositionProperty静态,然后在静态构造函数中注册它。我的问题是当我的PropertyChangeCallback事件发生时我无法访问该类的本地实例。

如何在XAML中设置属性并仍在C#代码中获取on属性更改事件?

是否有比依赖属性更好的解决方案?


以下是我实施答案后BoardSquare的工作代码。

    public partial class BoardSquare : UserControl
{
    static BoardSquare()
    {
        XPositionProperty =
             DependencyProperty.Register("XPosition", typeof(int),
             typeof(BoardSquare), new PropertyMetadata(
                 new PropertyChangedCallback((objectInstance, args) =>
                 {
                     BoardSquare boardSquare = (BoardSquare)objectInstance;
                     boardSquare.Location.X = (int)args.NewValue;
                     boardSquare.resetBackgroundColorToPosition();
                 })));
        YPositionProperty =
            DependencyProperty.Register("YPosition", typeof(int),
            typeof(BoardSquare), new PropertyMetadata(
                new PropertyChangedCallback((objectInstance, args) =>
                {
                    BoardSquare boardSquare = (BoardSquare)objectInstance;
                    boardSquare.Location.Y = (int)args.NewValue;
                    boardSquare.resetBackgroundColorToPosition();
                })));
    }

    public BoardSquare()
    {
        InitializeComponent();
        Location = new BoardLocation(Int32.MinValue, Int32.MinValue);


    }

    private void resetBackgroundColorToPosition()
    {
        this.Background = (Brush)(new ColorEnumToBrushesConverter()).Convert(Location.GetSquareColor(), typeof(BlackWhiteColor), null, null);
    }

    public static readonly DependencyProperty XPositionProperty;
    public static readonly DependencyProperty YPositionProperty;

    public int XPosition
    {
        get
        {
            return (int)GetValue(XPositionProperty);
        }
        set
        {
            SetValue(XPositionProperty, value);
        }
    }

    public int YPosition 
    { 
        get
        {
            return (int)GetValue(YPositionProperty);
        }
        set
        {
            SetValue(YPositionProperty, value);
        }
    }

    public BoardLocation Location { get; set; }
}

2 个答案:

答案 0 :(得分:2)

PropertyChangedCallback 第一个参数是本地实例(顺便说一下,你最好将它命名为 obj 而不是 value 避免混淆)。您必须将此DependencyObject投射到BoardSquare,这就是全部。

public static readonly DependencyProperty XPositionProperty =
    DependencyProperty.Register("XPosition", typeof(int), typeof(BoardSquare),
                                new PropertyMetadata(new PropertyChangedCallback((obj, args) => {
                                    BoardSquare bs = obj as BoardSquare;
                                    bs.Location.X = (int)args.NewValue;
                                    bs.resetBackgroundColorToPosition();
                                })));

答案 1 :(得分:0)

如果我正确理解了您的问题,那么您正尝试使用自己的WPF证书属性覆盖。我认为这不是必要的。如果XPosition已经是WPF证书属性,那么您所要做的就是在usercontrol中使用getter / setter创建一个属性,并使用setter调用INotifypropertychanged。在这种情况下你不需要依赖属性,除非你只想要相同的名字但行为不同,为什么你想要呢?