2012-08-27 60 views
4

我在包含對象的WPF應用程序中有一個DataGrid控件。該對象的布爾屬性可以通過用戶操作進行更改。當該屬性的值發生更改時,我需要該行的樣式進行更改。如何更改WPF DataGrid控件中該行中項目的屬性發生更改的行的樣式

我寫了下降的一類從StyleSelector

public class LiveModeSelector : StyleSelector { 

    public Style LiveModeStyle { get; set; } 
    public Style NormalStyle { get; set; } 

    public override Style SelectStyle(object item, DependencyObject container) { 
     DataGridRow gridRow = container as DataGridRow; 
     LPRCamera camera = item as LPRCamera; 
     if (camera != null && camera.IsInLiveMode) { 
      return LiveModeStyle; 
     } 
     return NormalStyle; 
    } 
} 

問題視圖模型類實現INotifyPropertyChanged,並引發PropertyChanged事件時,有關變化的特性。

// Note: The ModuleMonitor class implements INotifyPropertyChanged and raises the PropertyChanged 
// event in the SetAndNotify generic method. 
public class LPRCamera : ModuleMonitor, ICloneable { 

    . . . 

    public bool IsInLiveMode { 
     get { return iIsInLiveMode; } 
     private set { SetAndNotify("IsInLiveMode", ref iIsInLiveMode, value); } 
    } 
    private bool iIsInLiveMode; 

    . . . 

    /// </summary> 
    public void StartLiveMode() { 
     IsInLiveMode = true; 

     . . . 
    } 


    public void StopLiveMode() { 
     IsInLiveMode = false; 

     . . . 
    } 
} 

當用戶執行所需操作但該樣式不會更改時,該屬性的值會更改。

我已經在SelectStyle方法中放置了一個斷點,並且在控件第一次加載時看到了斷點,但是當屬性的值發生變化時它不會被觸發。

我錯過了什麼?

回答

4

我找到了一種方法來解決@Rachel對我的問題的回答。但是,代碼細節有所不同,我想確切地說明哪些方法可行。

的第一步是兩個不同的Styles組合成一個爲DataGridRow類:

<Style TargetType="DataGridRow" x:Key="CameraStyle"> 
    <Setter Property="Foreground" Value="{DynamicResource TextForeground}" /> 
    <Setter Property="Background" Value="{DynamicResource DataBackground}" /> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Path=IsInLiveMode}" Value="True"> 
      <Setter Property="Foreground" Value="Red" /> 
      <Setter Property="Background" Value="Yellow" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

第二步是到DataGrid控制的RowStyle屬性設置爲這種新的風格:

<DataGrid . . . 
      RowStyle={StaticResource CameraStyle}"> 
      . . . 
</DataGrid> 

這可行。當用戶將與該行相關聯的LPRCamera放入實時模式時,該行的前景和背景會發生變化,當它從現場模式中移出時,該行會變回正常狀態,這正是我所要做的。

Thanks @Rachel!

+0

我正要編輯我的答案,根據你的評論提出這個建議,但我看到你已經爲自己想出了這個答案:) :) – Rachel

+0

這個問題有一個有趣的小轉折。事實證明,當我第一次嘗試這個時,只有第一行第一列的顏色發生了變化。如果您將相機放在任何其他行中進入實時模式,則顏色不會改變。事實證明,我在我的app.xaml中爲'DataGridCell'類創建了一個樣式,並且正在改變'DataGridRow'類的顏色。我改變了app.xaml中的樣式,所以它適用於'DataGridRow'類並且一切正常。因此,本課將確保您始終處理同一類的樣式,最好是'DataGridRow'類! –

4

我不認爲StyleSelector會偵聽PropertyChange通知,因此在IsInLiveMode屬性發生更改時不會重新運行。

取而代之,根據IsInLiveMode將自己的風格放入DataTrigger,並且隨着屬性更改通知的提出,它將被重新評估。

<DataGrid.Resources> 
    <Style TargetType="{x:Type DataGridRow}" x:Key="Style1"> 
     <Setter Property="Background" Value="Red" /> 
    </Style> 
    <Style TargetType="{x:Type DataGridRow}" x:Key="Style2"> 
     <Setter Property="Background" Value="Blue" /> 
    </Style> 
</DataGrid.Resources> 

<DataGrid.Style> 
    <Style TargetType="{x:Type DataGrid}"> 
     <Setter Property="RowStyle" Value="{StaticResource Style1}" /> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ElementName=MyDataGrid, Path=DataContext.IsInLiveMode}" Value="True"> 
       <Setter Property="RowStyle" Value="{StaticResource Style2}" /> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</DataGrid.Style> 
+0

謝謝,這是有道理的。只有一個問題:通過將'ItemsSource'屬性綁定到'LPRCamera'對象的'ObservableCollection'來填充'DataGrid'。該集合不存儲在任何東西的'DataContext'中。如何讓'DataTrigger'綁定到被引用的'DataGrid'的特定行中特定的'LPRCamera'對象? –

相關問題