1

或者:如何通過兩個依賴屬性的數據綁定來訂閱由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事件,但它始終爲空。正因爲如此,我覺得我缺乏一些東西。

回答

0

要設置這意味着視圖模型的結合模式爲「單向」將永遠不會得到更新時,在視圖中值的變化。將綁定模式更改爲「雙向」,然後重試。

另外,請檢查您是否正在改變「DisplayControlValues」或該類只是性能的完整實例,因爲您的綁定設置爲僅火的時候,整個實例的變化,而不是它的性能。

除此之外,請記住,您可以使用Binding.ElementName屬性綁定兩個不同控件的屬性,這將使您無需創建視圖模型,除非您身後的代碼中有任何內容當這些值改變時需要做。

如果您發佈更多的代碼和XAML它會更容易找到最合適的方式來解決問題。

+0

謝謝您的回答Murven,我添加了更多的細節,我的職務。我也嘗試了雙向綁定和相同的結果。你提到我的綁定是爲整個實例更改設置的,我在哪裏可以控制如何只定位屬性更改,也許這就是我的問題。 – Luciano

+0

A結合僅監視在它被綁定到,而不是該實例,這意味着您結合ZoomGraphControlValues不監控上ZoomGraphControlValues.Source任何改變,例如內部的屬性實例的變化。您需要創建一個特定的綁定到該屬性,以使其監視更改。您可以通過將ControlValues屬性設置爲null,然後在對其中一個屬性進行更改後再次將其設置爲您正在使用的實例來測試此理論,這應該強制綁定觸發並讓您確定原因。 – Murven

+0

感謝您的建議穆文,使用null幫助我強制檢查,它的工作原理。你所有的建議都很棒,並幫助我理解我的問題。我會想盡量地結合用戶的控制直接控制你推薦的,但在我的情況下(在編程上創建綁定),我有成功的問題,但這不是realated我原來的問題,所以我將開始新的問題。 – Luciano

相關問題