或者:如何通过两个依赖属性的数据绑定来订阅由INotifyPropertyChanged定义的PropertyChanged事件?如何绑定属于两个不同控件的两个依赖项属性?
我在我的主窗口中有两个单独的用户控件。一个控件包含影响其他控件的参数,我们称之为显示控件。我希望参数控件充当显示控件的数据源,以便在参数控件中更改参数时,显示控件将进行侦听并作出相应反应。
为此,我创建了一个实现INotifyPropertyChanged的类,该类存储这些参数并在两个控件中创建此类类型的依赖项属性。我期待如果我绑定一个控制属性到另一个我会得到所需的行为,但不幸的是我缺少重要的东西,因为显示控件没有反应。
在对调试器进行更仔细的检查时,我注意到当属性发生更改时,我的事件PropertyChangedEventHandler PropertyChanged始终为空,并且我读取的所有内容都表示没有人在侦听。
由于显示控制实时创建,我要创建程序的结合是这样的:
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接口的参数类捕获的,但因为没有人在监听,所以事件处理程序为null,这里是我卡住的地方。
非常感谢您的帮助!
这里有更多的细节要求:
我有一个公开,改变另一个控件的行为的参数一个用户控制。此控件具有一个依赖项属性,其中包含参数详细信息并实现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事件,但它始终为空。正因为如此,我觉得我缺乏一些东西。
谢谢您的回答Murven,我添加了更多的细节,我的职务。我也尝试了双向绑定和相同的结果。你提到我的绑定是为整个实例更改设置的,我在哪里可以控制如何只定位属性更改,也许这就是我的问题。 – Luciano
A结合仅监视在它被绑定到,而不是该实例,这意味着您结合ZoomGraphControlValues不监控上ZoomGraphControlValues.Source任何改变,例如内部的属性实例的变化。您需要创建一个特定的绑定到该属性,以使其监视更改。您可以通过将ControlValues属性设置为null,然后在对其中一个属性进行更改后再次将其设置为您正在使用的实例来测试此理论,这应该强制绑定触发并让您确定原因。 – Murven
感谢您的建议穆文,使用null帮助我强制检查,它的工作原理。你所有的建议都很棒,并帮助我理解我的问题。我会想尽量地结合用户的控制直接控制你推荐的,但在我的情况下(在编程上创建绑定),我有成功的问题,但这不是realated我原来的问题,所以我将开始新的问题。 – Luciano