2013-08-14 5 views
0

У меня есть простой набор данных, который имеет столбцы, автогенерируемые и привязанные к источнику элемента. Этот элемент источника обновляется через определенные промежутки времени, и я не могу найти способ запуска события для одной ячейки. Я хочу изменить цвет ячейки на основе, если обновление источника данных изменило предыдущее значение ячейки.WPF Autogenerated DataGrid Cell изменил событие при привязке к ItemSource

Я посмотрел Highlighting cells in WPF DataGrid when the bound value changes, а также http://codefornothing.wordpress.com/2009/01/25/the-wpf-datagrid-and-me/, но я все еще не уверен, как это осуществить. Некоторый пример кода был бы очень полезен для начала работы по правильному пути.

ответ

1

Если вы привязываетесь к DataTable, я не думаю, что это было бы продуктивным путем, чтобы спуститься вниз. Выполнение любого стиля, основанного на содержимом связанного DataTable DataGrid, практически невозможно в WPF. Есть несколько предложений по StackOverflow, но они обычно довольно хаки, управляются событиями (как правило, это плохие новости в WPF) и кошмар для обслуживания.

Если, однако, объект ItemsSource, к которому вы привязываетесь, является ObservableCollection, где RowViewModel - это класс, который представляет данные в одной строке DataGrid, тогда это не должно быть слишком плохо. Убедитесь, что RowViewModel реализует INotifyPropertyChanged и просто обновляет отдельные RowViewModels с их обновленными данными. Затем вы можете добавить логику, чтобы открыть дополнительное свойство в RowViewModel, которое указывает, является ли какое-то конкретное значение новым - просто используйте некоторые стили/триггеры в XAML, чтобы установить цвет фона на основе значения этого нового свойства.

Вот пример последнего: если вы редактируете одно из значений в первом столбце, оно превратит ячейку в красный цвет. То же самое произойдет, если вы измените значение в ItemViewModel программно с помощью обновления базы данных.

Часть XAML:

<Window x:Class="ShowGridUpdates.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Binding="{Binding Item1, UpdateSourceTrigger=PropertyChanged}"> 
       <DataGridTextColumn.CellStyle> 
        <Style TargetType="DataGridCell"> 
         <Style.Setters> 
          <Setter Property="Background" Value="Blue"/> 
          <Setter Property="Foreground" Value="White"/> 
         </Style.Setters> 
         <Style.Triggers> 
          <DataTrigger Binding="{Binding Item1Changed}" Value="True"> 
           <Setter Property="Background" Value="Red"/> 
          </DataTrigger> 
         </Style.Triggers> 
        </Style> 
       </DataGridTextColumn.CellStyle> 
      </DataGridTextColumn> 
      <DataGridTextColumn Binding="{Binding Item2}"/> 
     </DataGrid.Columns> 
    </DataGrid> 
</Grid> 

Кодекс-Behind:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = new ViewModel(); 
    } 
} 

public class ViewModel : PropertyChangedNotifier 
{ 
    public ViewModel() 
    { 
     Items = new ObservableCollection<ItemViewModel>() 
     { 
      new ItemViewModel(){Item1="Item1FistValue", Item2="Item2FirstValue"}, 
      new ItemViewModel(){Item1="whocareswhatvalue", Item2="Icertainlydont"} 
     }; 

     //just to get the initial state correct 
     foreach (var item in Items) 
     { 
      item.Item1Changed = false; 
     } 
    } 

    private ObservableCollection<ItemViewModel> _items; 

    public ObservableCollection<ItemViewModel> Items 
    { 
     get 
     { 
      return _items; 
     } 
     set 
     { 
      _items = value; 
      OnPropertyChanged("Items"); 
     } 
    } 
} 

public class ItemViewModel : PropertyChangedNotifier 
{ 
    private string _item1; 
    private string _item2; 

    private bool _item1Changed; 

    public bool Item1Changed 
    { 
     get 
     { 
      return _item1Changed; 
     } 
     set 
     { 
      _item1Changed = value; 
      OnPropertyChanged("Item1Changed"); 
     } 
    } 

    public string Item1 
    { 
     get 
     { 
      return _item1; 
     } 
     set 
     { 
      if (_item1 != value) 
       Item1Changed = true; 
      else 
       Item1Changed = false; 

      _item1 = value; 
      OnPropertyChanged("Item1"); 
     } 
    } 

    public string Item2 
    { 
     get 
     { 
      return _item2; 
     } 
     set 
     { 
      _item2 = value; 
      OnPropertyChanged("Item2"); 
     } 
    } 
} 

public class PropertyChangedNotifier : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    public void OnPropertyChanged(string propertyName) 
    { 
     var propertyChanged = PropertyChanged; 
     if (propertyChanged != null) 
     { 
      propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 
+0

спасибо за ответ Эндрю. Я новичок в WPF, поэтому у вас есть короткий пример для этого, на который я мог бы смотреть? спасибо – ssarangi

+0

Там я добавил простое демонстрационное приложение - дайте мне знать, если он не сработает для вас. – Andrew

+0

Спасибо, Андрей ... это сработало :) – ssarangi

Смежные вопросы