我基本上和这个人有同样的问题: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; }
}
答案 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。在这种情况下你不需要依赖属性,除非你只想要相同的名字但行为不同,为什么你想要呢?