2011-02-09 30 views
1

我有一個Silverlight DataGrid綁定到MyObjects的集合。 MyObject有一個布爾字段IsHighlighted。 如果此值爲true,我想更改行的背景顏色。如果它變成虛假的話,它會改回來。如何更改Silverlight DataGridRow的背景顏色?

我已經嘗試過使用Loading_Row事件(as explained here),但它不適用於我,因爲此事件僅被調用一次,並且此時objetcs的布爾值都設置爲false(僅限於此事件當另一個組件選擇時變成truc;這起作用,我檢查了這些值)。

任何人都有線索?提前致謝 !

更新:我做了一個測試應用程序來說明,它再現了我的問題。

<navigation:Page x:Class="AViews.Tests" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
      mc:Ignorable="d" 
      xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
      DataContext="{Binding RelativeSource={RelativeSource Self}}" 
      d:DesignWidth="640" d:DesignHeight="480" 
      Title="Tests Page"> 
    <Grid x:Name="LayoutRoot"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 

     <sdk:DataGrid Grid.Row="0" ItemsSource="{Binding AllItems, Mode=TwoWay}" AutoGenerateColumns="False" LoadingRow="DataGrid_LoadingRow"> 
      <sdk:DataGrid.Columns> 
       <sdk:DataGridTextColumn Binding="{Binding Value1}" Header="Value1" /> 
       <sdk:DataGridTextColumn Binding="{Binding Value2}" Header="Value2"/> 
       <sdk:DataGridCheckBoxColumn Binding="{Binding IsHighlighted}" Header="Is Highlighted" /> 
      </sdk:DataGrid.Columns> 
     </sdk:DataGrid> 

     <Button Content="Change !" Grid.Row="1" HorizontalAlignment="Left" Click="Button_Click" /> 

    </Grid> 
</navigation:Page> 

public partial class Tests : Page, INotifyPropertyChanged 
{ 
    private SampleConverter bgConverter = new SampleConverter(); 
    Random r = new Random(); 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    private ObservableCollection<Sample> allItemsField = new ObservableCollection<Sample>(); 
    public ObservableCollection<Sample> AllItems 
    { 
     get 
     { 
      return this.allItemsField; 
     } 

     set 
     { 
      if (this.allItemsField != value) 
      { 
       this.allItemsField = value; 
       this.OnPropertyChanged("AllItems"); 
      } 
     } 
    } 

    public Tests() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnNavigatedTo(NavigationEventArgs e) 
    { 
     var tmp = Enumerable.Range(0, 100).Select(f => new Sample(f)).ToList(); 
     foreach (var item in tmp) 
     { 
      item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged); 
     } 

     var coll = new ObservableCollection<Sample>(tmp); 

     this.AllItems = coll; 
    } 

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     this.OnPropertyChanged("AllItems"); 
    } 

    private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e) 
    { 
     Binding b = new Binding("IsHighlighted") 
     { 
      Mode = BindingMode.OneWay, 
      Converter = this.bgConverter, 
      ValidatesOnExceptions = true 
     }; 

     e.Row.SetBinding(DataGridRow.BackgroundProperty, b); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     foreach (var item in this.AllItems) 
     { 
      item.IsHighlighted = r.Next(1000) % 2 == 0; 
     } 
    } 
} 

public class Sample: INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    private string value1Field = string.Empty; 
    public string Value1 
    { 
     get 
     { 
      return this.value1Field; 
     } 

     set 
     { 
      if (this.value1Field != value) 
      { 
       this.value1Field = value; 
       this.OnPropertyChanged("Value1"); 
      } 
     } 
    } 

    private string value2Field = string.Empty; 
    public string Value2 
    { 
     get 
     { 
      return this.value2Field; 
     } 

     set 
     { 
      if (this.value2Field != value) 
      { 
       this.value2Field = value; 
       this.OnPropertyChanged("Value2"); 
      } 
     } 
    } 

    private bool isHighlightedField = false; 
    public bool IsHighlighted 
    { 
     get 
     { 
      return this.isHighlightedField; 
     } 

     set 
     { 
      if (this.isHighlightedField != value) 
      { 
       this.isHighlightedField = value; 
       this.OnPropertyChanged("IsHighlighted"); 
      } 
     } 
    } 

    public Sample(int index) 
    { 
     this.Value1 = string.Format("Value1 #{0}", index); 
     this.Value2 = string.Format("Value2 #{0}", index); 
    } 
} 

public class SampleConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     bool val = (bool)value; 
     SolidColorBrush ret = val ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Green); 
     return ret; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

而結果上可以看到那些照片:

當我第一次在頁面上到達。 Start

我點擊按鈕,它將一些(隨機)值設置爲true。如您所見,綁定已更新,而不是UI。 enter image description here

我使用滾動條,走到最後,然後回來,哦!精彩!所有行是經過正確的彩色:-(

enter image description here

回答

2

請參見下面的鏈接,通過改變DataGridRow 結合的BackgroundRectangleFill屬性的控件模板解決這個問題。你可以使用一個boolConverter從轉換IsHighlightedSolidColorBrush

Silverlight DataGrid row color binding