或者:如何通过两个依赖属性的数据绑定来订阅由INotifyPropertyChanged定义的PropertyChanged事件?
我的主窗口中有两个独立的用户控件。一个控件包含影响另一个控件的参数,我们称之为显示控件。我希望参数控件充当显示控件的数据源,这样当我更改参数控件中的参数时,显示控件就会监听并做出相应的反应。
为此,我创建了一个实现INotifyPropertyChanged的类,该类存储这些参数并在两个控件中创建此类类型的依赖项属性。我期待如果我将一个控件属性绑定到另一个控件属性,我会得到所需的行为,但不幸的是我错过了一些重要的东西,因为显示控件没有反应。
在仔细检查调试器时,我注意到我的事件PropertyChangedEventHandler PropertyChanged在属性发生变化时始终为null,并且我读过的所有内容都表明没有人正在侦听。
因为显示控件是实时创建的,所以我必须以编程方式创建绑定:
var DispayControlValuesBinding = new Binding();
DispayControlValuesBinding.Source = DisplayControlsControl;
DispayControlValuesBinding.Path = new PropertyPath("DisplayControlValues");
DispayControlValuesBinding.Mode = BindingMode.OneWay;
DispayControlValuesBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
DispayControlValuesBinding.NotifyOnSourceUpdated = true;
//
graph.SetBinding(Graph.DisplayControlValuesProperty, DisplayControlValuesBinding);
两个控件都有一个名为DispayControlValues的依赖项属性。我尝试将DisplayControlControl的DisplayControlValues属性绑定到图形控件的DisplayControlValues属性。
当应用程序运行时,它会初始化参数控件,然后使用用户请求以编程方式创建显示控件并进行绑定。然后我在参数控件中更改一个值,这是实现INotifyPropertyChanged接口的参数类捕获但是因为没有人在监听,所以事件处理程序为空,这就是我被卡住的地方。
非常感谢您的帮助!
以下是详细信息:
我有一个用户控件,它公开了改变另一个控件行为的参数。此控件具有依赖项属性,该属性包含参数详细信息并实现INotifyPropertyChanged接口。
这是班级:
public class ZoomGraphControlValues : INotifyPropertyChanged
{
private bool _displayRaw;
public bool DisplayRaw
{
get { return _displayRaw; }
set
{
_displayRaw = value;
OnPropertyChanged(new PropertyChangedEventArgs("DisplayRaw"));
}
}
private bool _enableFit;
public bool EnableFit
{
get { return _enableFit; }
set
{
_enableFit = value;
OnPropertyChanged(new PropertyChangedEventArgs("EnableFit"));
}
}
public ZoomGraphControlValues()
{}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
这是依赖属性:
public ZoomGraphControlValues ControlValues
{
get { return (ZoomGraphControlValues)GetValue(ControlValuesProperty); }
set { SetValue(ControlValuesProperty, value); }
}
public static readonly DependencyProperty ControlValuesProperty =
DependencyProperty.Register("ControlValues", typeof(ZoomGraphControlValues), typeof(ZoomGraphControls), new PropertyMetadata(null, OnControlValuesPropertyChanged));
private static void OnControlValuesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var myObj = d as ZoomGraphControls;
myObj.OnControlValuesPropertyChanged(e);
}
private void OnControlValuesPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if (ControlValues != null)
{
IniValues();
}
}
然后我有显示用户控件。此控件还实现了与其他控件相同类型的依赖项属性,并且我希望此控件成为绑定的目标,因此当我更改参数控件中的值时,此控件将反映更改。
以下是此控件的依赖项属性:
public ZoomGraphControlValues ZoomGraphControlValues
{
get { return (ZoomGraphControlValues)GetValue(ZoomGraphControlValuesProperty); }
set { SetValue(ZoomGraphControlValuesProperty, value); }
}
public static readonly DependencyProperty ZoomGraphControlValuesProperty =
DependencyProperty.Register("ZoomGraphControlValues", typeof(ZoomGraphControlValues), typeof(zoomGraph), new PropertyMetadata(null, OnZoomGraphControlValuesPropertyChanged));
private static void OnZoomGraphControlValuesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var myObj = d as zoomGraph;
myObj.OnZoomGraphControlValuesPropertyChanged(e);
}
private void OnZoomGraphControlValuesPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if (ZoomGraphControlValues != null)
{
// update the control with the new parameters
ShowRawData(ZoomGraphControlValues.DisplayRaw);
SetChartBehabiour();
}
}
自应用程序循环开始以来,参数控件已初始化。显示控件根据用户请求创建到选项卡中,因此我必须以编程方式创建控件,从而创建绑定:
//create the tab and wire tab events
//…
//create a display control
var graph = new zoomGraph();
// initialize the parameters class
var zgcv = new ZoomGraphControlValues
{
DisplayRaw = true,
ChartBehaviour = ChartBehaviour.Zoom
};
//assign the parameters class to the parameters user control dependency property
ZoomGraphControlsControl.ControlValues = zgcv;
//create the binding of the parameter control to the display control by linking their respective dependency properties
var zoomGraphControlValuesBinding = new Binding();
zoomGraphControlValuesBinding.Source = ZoomGraphControlsControl;
zoomGraphControlValuesBinding.Path = new PropertyPath("ControlValues");
zoomGraphControlValuesBinding.Mode = BindingMode.TwoWay;
zoomGraphControlValuesBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
zoomGraphControlValuesBinding.NotifyOnSourceUpdated = true;
zoomGraphControlValuesBinding.NotifyOnTargetUpdated = true;
graph.SetBinding(zoomGraph.ZoomGraphControlValuesProperty, zoomGraphControlValuesBinding);
//…
// add the user control to a tab
当我更改参数控件中的参数时,我可以看到它尝试触发OnPropertyChanged事件,但它始终为null。因此,我认为我缺少一些东西。
答案 0 :(得分:0)
您正在将绑定模式设置为“OneWay”,这意味着当视图中的值更改时,视图模型将永远不会更新。将绑定模式更改为“TwoWay”,然后重试。
另外,检查您是否正在更改“DisplayControlValues”的完整实例或仅更改该类的属性,因为您的绑定仅在整个实例更改时设置为触发,而不是其属性。
除此之外,请记住,您可以使用Binding.ElementName属性绑定两个不同控件的属性,这将使您无需创建视图模型,除非您需要的代码中有任何内容当这些值发生变化时要做。
如果您发布更多代码和XAML,将更容易找到最合适的方法来解决您的问题。