Search code examples
c#wpfdata-bindingdatagriddatatrigger

Datagrid datatrigger not fired when value changes


I have a dataGridwith columns that have bindings to some columns in a data table

<DataGrid x:Name="WatchersGrid" ItemsSource="{Binding GroupWatchers}" AutoGenerateColumns="False" SelectedItem="{Binding SelectedItem}" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding  Path=[Name]}"/>
                        <DataGridTextColumn Header="Value" Binding="{Binding Path=[Value]}">
                            <DataGridTextColumn.ElementStyle>
                                <Style>
                                    <Setter Property="TextBlock.TextWrapping" Value="Wrap"/>
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                        <DataGridTextColumn Header="InRange" Binding="{Binding [IsInRange]}"/>
            </DataGrid.Columns>
                    <DataGrid.RowStyle>
                        <Style TargetType="DataGridRow">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding [IsInRange]}" Value="False">
                                    <Setter Property="Foreground" Value="Crimson"></Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </DataGrid.RowStyle>
        </DataGrid>

i have a data trigger on the "IsInRange" column that sets the foreground property to red if the value is false. the value inside the data grid column changes but the color property dosent change. i tried to NotifyPropertyChanged("[IsInRange]"); when my value is changing but that didnt help any ideas?

Edit: My ViewModel

public class WatcherControlViewModel : INotifyPropertyChanged
{
  private DataTable _dt;
  private string _groupName;
  public DataRow[] GroupWatchers{get {return _dt.Select("Group = '" + GroupName + "'");}}
  public WatcherControlViewModel(DataTable dt, string name)
    {
        _dt = dt;
        _groupName = name;
       _dt.RowChanged += DataTableChangedEvent;
    }

    private void DataTableChangedEvent(object sender, DataRowChangeEventArgs e)
    {
        NotifyPropertyChanged("GroupWatchers");
        NotifyPropertyChanged("IsInRange");
    }
}

thanks


Solution

  • It really depends on your ViewModel and how you're binding to it. Implying from your XAML, your ViewModel should look something like this:

    public class MyViewModel
    {
        public DataTable WatchersGrid { get; set; }
    
        public MyViewModel()
        {
            WatchersGrid = new MyDataTable();
        }
    }
    

    And your binding should look like this:

    public partial class Window1 : Window
    {
        private MyViewModel vm;
    
        public Window1()
        {
            InitializeComponent();
        }
    
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            vm = new MyViewModel();
            DataContext = vm;
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            vm.WatchersGrid.Rows[0]["IsInRange"] = !(bool)vm.WatchersGrid.Rows[0]["IsInRange"];
        }
    }
    

    Note the test button. It switches IsInRange value between true and false for the first row only, for testing purposes.

    And the result:

    enter image description hereenter image description here