2011-10-18 26 views
1

我想更改由第二個依賴屬性(ViewType)的更改更改觸發的UserControl中的依賴項屬性(Mode)的狀態。如何編寫數據觸發器,以基於第二個依賴項屬性的更改更改依賴項屬性的值?

我試圖定義一個DataTrigger如下,但由於某種原因它不工作:

<UserControl.Resources> 
    <Style TargetType="{x:Type UserControls:MyUserControl}"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ViewType}" Value="ViewType2"> 
       <Setter Property="Mode" Value="Logon"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</UserControl.Resources> 

爲了驗證我的結合是正常工作我寫了下面的測試XAML在相同的用戶控件:

<Style x:Key="butstyle"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ViewType}" Value="ViewType2"> 
       <Setter Property="Control.Foreground" Value="White"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 

當我將此樣式分配給按鈕時,我發現前景顏色在正確的時間變爲白色,這證明我的Binding to ViewType正在工作。

我似乎需要使用usercontrol.resources下的樣式(如上面的第一個代碼塊),但「Mode」屬性從不設置。

這是正確的方法嗎?如果可能的話,我想盡量保留在XAML中,但是如果觸發器與視覺元素沒有直接關係,觸發器應該如何工作,我不太確定。

在相關的情況下,「ViewType」綁定屬性在父UserControl中定義,並且「Mode」屬性在MyUserControl上定義。

更新:

我用了一個轉換器,以找出我的觸發器被調用,但是我的二傳手是不是要訂婚的某些原因。這是我正在嘗試設置的DP的代碼。調用neitehr set()和OnModeChanged()的斷點。我的依賴屬性有什麼問題嗎?

public enum ModeStates { Logon, NextState } 

    public ModeStates Mode 
    { 
     get { return (ModeStates)GetValue(ModeProperty); } 
     set { SetValue(ModeProperty, value); } 
    } 

    protected static readonly DependencyProperty ModeProperty = DependencyProperty.Register(
      "Mode", typeof(ModeStates), typeof(MyUserControl), 
      new FrameworkPropertyMetadata(new PropertyChangedCallback(OnModeChanged)) 
      ); 


    private static void OnModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 

      // ....... 

    } 

更新:

我能夠使用DependencyPropertyDescriptor.AddValueChanged()來解決一個非常乾淨的時尚我的問題。

+0

這是評論,而不是aswer,因爲我沒有測試它。你可以用轉換器來做到這一點。你有沒有理由不能在你綁定的對象中做這件事? – Paparazzi

+0

如何使用DependencyPropertyDescriptor.AddValueChanged()來解決你的問題?你能提供一些代碼嗎? – Gintama

+0

對不起,這篇文章來自很多年以前,我很久以前就停止了這個語言和框架的工作,我也不記得細節。 – Locksleyu

回答

3

如果在UserControl中定義了有關依賴項屬性,則需要設置它的樣式屬性,而不是在資源內添加默認樣式。

在XAML

<UserControl.Style> 
    <Style TargetType="{x:Type UserControls:MyUserControl}"> 
     <!-- Triggers -- > 
    </Style> 
</UserControl.Style> 
+0

感謝Adam的迴應。我的印象是,任何具有目標類型和名稱的Style都會自動分配給所有匹配的目標,所以我不明白你的方法會有什麼不同。不過,無論如何,我仍然嘗試過,但仍然得到相同的結果(二傳手永遠不會被調用)。還有什麼想法?我添加了一個關於DP的原始文章的澄清(「如果它的相關,」ViewType「綁定屬性在父UserControl中定義,並且」Mode「屬性在MyUserControl上定義)。」) – Locksleyu

+1

它會是如果你提供了控制手術,這會有幫助。你對一個默認的樣式是正確的(不是唯一的鍵,targettype),但是它將被應用到它定義的UserControl的所有子節點。如果這個usercontrol和你試圖在觸發器中實現的那個相同,不要使用(因爲它本身不是孩子) –

+0

也檢查輸出窗口中的綁定錯誤。 –

1

另外設置的樣式內嵌到Adam's answer,你在任何地方設置Mode財產在<UserControl>標籤?如果這樣做,它會覆蓋觸發值。

此外,有時我遇到觸發值沒有設置的問題,除非在樣式中還定義了默認值。

例如,有時這是不行的

<UserControl.Style> 
    <Style TargetType="{x:Type UserControls:MyUserControl}"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ViewType}" Value="ViewType2"> 
       <Setter Property="Mode" Value="Logon"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</UserControl.Style> 

,而這確實

<UserControl.Style> 
    <Style TargetType="{x:Type UserControls:MyUserControl}"> 
     <Setter Property="Mode" Value="{x:Null}"/> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ViewType}" Value="ViewType2"> 
       <Setter Property="Mode" Value="Logon"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</UserControl.Style> 
+0

感謝Rachel的想法。我沒有在UserControl的XAML中設置Mode屬性的任何地方,但是在我設置它的位置的代碼中有幾個地方(基於其他事件,例如按下按鈕等)。我希望這不是問題,因爲Mode的價值取決於幾種不同的條件。可能稍微好一點的名字就是'狀態',因爲它反映了任何時候的控制狀態。 – Locksleyu

+1

@Locksleyu如果您在對象上明確定義屬性,無論是在XAML還是代碼隱藏中,它都會覆蓋任何樣式或觸發值。另一種方法是在Style中設置值,例如使用綁定,因爲允許Triggered值覆蓋它。有關應用DependencyProperties的順序的更多信息,請參閱以下鏈接:http://msdn.microsoft.com/en-us/library/ms743230.aspx – Rachel

+0

Rachel,通過「在對象上明確定義屬性」是你指的是設置值(即Mode = NextState;在代碼中),還是你指的是創建依賴屬性本身?我通過DependencyProperty.Register()在代碼中創建了一個自定義依賴屬性,這是否意味着我無法通過datatrigger/setter安全地設置該DP? – Locksleyu