我有一个使用Device
的课程INotifyPropertyChanged
,经过测试并且有效。
现在我有一个deviceMonitor
,它是此设备的UI表示形式。在代码中我引用了Device
,我想将设备中的更改链接到UI中的更改(不需要两种方式,但单击deviceMonitor
应该调用{的某个函数{1}})
我正在使用表达式Blend和VS2015,因此非常欢迎基于点击以使其工作的指导。
这是device
device
然后是GUI的xaml.cs,这里我引用了包含public class Device : INotifyPropertyChanged
{
public string Name { ... } //uses NotifyPropertyChanged in the set
// other properties and their relative private vars.
}
的dll:
Device
然后是XAML
public partial class DeviceControl : UserControl
{
public Device myDevice = new Device();
public DeviceControl()
{
InitializeComponent();
// here I tried setting the datacontest to the myDevice
// also tried to set the dataContext in Blend and here grab a
// reference to it and store it in myDevice. But nothing workerd
}
public void ChangeDevName()
{
this.myDevice.DeviceName = "Test";
//UI Representation of deviceName never changed
}
}
答案 0 :(得分:0)
这可能有效:
在DeviceControl
UserControl中,为控件的OnLoaded
和OnUnloaded
发送事件。
在事件处理程序的代码隐藏中,订阅/取消订阅UserControl的DataContext(PropertyChanged
)的this.DataContext
事件;像这样:
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (this.DataContext is INotifyPropertyChanged)
{
((INotifyPropertyChanged)this.DataContext).PropertyChanged += OnDataContextPropertyChanged;
}
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
if (this.DataContext is INotifyPropertyChanged)
{
((INotifyPropertyChanged)this.DataContext).PropertyChanged -= OnDataContextPropertyChanged;
}
}
private void OnDataContextPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// You could also just update every time something is changed.
// As an example you could check for the "Name" property being changed.
if (e.PropertyName == nameof(Device.Name))
{
title.Text = this.DataContext.Name;
}
}
要做的重要提示是if (this.myDevice is INotifyPropertyChanged)
检查。
确保Device
类继承自INotifyPropertyChanged
。
提供它,它会将Device
作为您的DataContext(this.DataContext
)投射到(INotifyPropertyChanged)
,以便您可以从PropertyChanged
订阅INotifyPropertyChanged
事件接口
然后,当DataContext
上的属性发生更改时,将触发您的处理程序。显然你可以在OnMyDevicePropertyChanged
的代码中放置你想做的事情,我只是用“名字”作为例子。
希望这有帮助!
修改强>
此外;您还可以在UserControl的代码隐藏中存储类型为Device
的私有字段。有点像:
private Device _viewModel; // You could also use the interface (like 'IDevice'), too.
然后在你的`OnLoaded'事件中,将它存储在字段中:
if (this.DataContext is INotifyPropertyChanged)
{
this.viewModel = this.DataContext;
// Wire up your PropertyChanged handler as before.
}
在您的OnUnloaded
事件中,如果它不为null,则取消订阅viewModel:
if (this.viewModel != null)
{
this.viewModel.PropertyChanged -= OnDataContextPropertyChanged;
}
当您将DataContext存储为字段时,这也为您提供了更多的灵活性,因为您可以在其他方法中使用它(如果您在代码中使用了更多 - 您不应该。 .. ;但它可以节省CPU时间,使其一直投入INotifyPropertyChanged。
为了将来参考,我会在您的项目中查看Implementing MVVM Practices。
祝你好运!答案 1 :(得分:0)
问题是覆盖私有设备,设置datacontext固定的东西。 这是最后一堂课:
public partial class DeviceControl : UserControl
private Device _device = new Device();
public DeviceControl()
{
InitializeComponnents();
this.DataContext = _device;
}
public void SetDevice(Device d)
{
//This fails:
//_device = d;
//This works
this.DataContext = d;
}