【发布时间】:2016-05-06 10:32:41
【问题描述】:
我正在制作一个应该记录鼠标位置的窗口。我创建了一个用户控件,它应该显示该位置标签的当前坐标并允许用户更改它们。
它很好用,除了当一个更新时它们都会改变。
我认为这与依赖属性是静态注册的事实有关。它们需要是依赖属性,因为我需要能够将它们从 xaml 绑定到我的模型。
如何让用户控件相互独立?
<UserControl x:Class="SapFormFiller.SerializableMouseEditorControl"
...
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60*"/>
...
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding LabelText}"></Label>
<Label Grid.Column="1" Content="{Binding SerializableMouseKeyboardEventArgs.X}"/>
<Label Grid.Column="2" Content="{Binding SerializableMouseKeyboardEventArgs.Y}"/>
<Button Grid.Column="3" Margin="0,0,0.4,0" Click="ButtonBase_OnClick">Edit</Button>
</Grid>
cs:
public partial class SerializableMouseEditorControl : UserControl
{
public static DependencyProperty LabelTextProperty = DependencyProperty.Register(
"LabelText", typeof (string), typeof (SerializableMouseEditorControl), new PropertyMetadata(default(string)));
public string LabelText
{
get { return (string) GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
public static DependencyProperty SerializableMouseKeyboardEventArgsProperty = DependencyProperty.Register(
"SerializableMouseKeyboardEventArgs", typeof (SerializableMouseKeyboardEventArgs), typeof (SerializableMouseEditorControl), new PropertyMetadata(new SerializableMouseKeyboardEventArgs()));
public SerializableMouseKeyboardEventArgs SerializableMouseKeyboardEventArgs
{
get { return (SerializableMouseKeyboardEventArgs) GetValue(SerializableMouseKeyboardEventArgsProperty); }
set { SetValue(SerializableMouseKeyboardEventArgsProperty, value); }
}
public SerializableMouseEditorControl()
{
InitializeComponent();
SerializableMouseKeyboardEventArgs = new SerializableMouseKeyboardEventArgs();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
SerializableMouseKeyboardEventArgs.Update();
}
}
SerializableMouseKeyboardEventArgs:
public class SerializableMouseKeyboardEventArgs : INotifyPropertyChanged
{
public int X
{
get { return _x; }
set
{
_x = value;
OnPropertyChanged("X");
}
}
public int Y
{
get { return _y; }
set
{
_y = value;
OnPropertyChanged("Y");
}
}
...
IKeyboardMouseEvents gkme;
private int _x = 0;
private int _y=0;
public override string ToString(){...}
public SerializableMouseKeyboardEventArgs()
{
gkme = Hook.GlobalEvents();
}
public void Update()
{
IsEditing = true;
gkme.MouseClick += Gkme_MouseClick;
}
private void Gkme_MouseClick(object sender, MouseEventArgs e)
{
if(e.Button==MouseButtons.Left)
{
this.X = e.X;
this.Y = e.Y;
}
else if (e.Button == MouseButtons.Right)
{
gkme.MouseClick -= Gkme_MouseClick;
IsEditing = false;
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
【问题讨论】:
-
您是否在
gkme.MouseClick -= Gkme_MouseClick;设置了断点以确保处理程序实际上已分离? -
问题很可能是您将
new SerializableMouseKeyboardEventArgs()创建为默认值。这使它在所有人之间共享。添加一个非静态 ctor 并从那里设置属性。 -
如果我将其设置为
default(),那么所有依赖属性都是null,并且在单击编辑按钮时会出现空引用异常。是的,处理程序成功分离。
标签: c# wpf data-binding user-controls dependency-properties