Search code examples
wpfmvvmwpfdatagriddatatrigger

DataGrid.RowStyle only works on initial binding


I have a DataTrigger applying a style to the Visibility property of a DataGrid row. The DataTrigger is working just fine on the initial binding of the DataGrid (ie - it sets the row visibility to collapsed if FilteredOut is true).

I have a ComboBox that sets the FilteredOut property to true or false for each item in the ObservableCollection AllPartMalfunctions depending upon what the user has selected in the ComboBox.

Here is my problem: after selecting an item in the ComboBox and setting the FilteredOut property for each item, the DataGrid rows do not refresh to be visible or collapsed and everything on the UI looks the same as it did before selecting anything in the ComboBox. What am I missing?

Here is the XAML:

<DataGrid ItemsSource="{Binding AllPartMalfunctions}"
          AutoGenerateColumns="False" Width="Auto">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Style.Triggers>
                <DataTrigger Binding="{Binding FilteredOut, Mode=TwoWay}" Value="True">
                    <Setter Property="Visibility" Value="Collapsed" />
                </DataTrigger>
                <DataTrigger Binding="{Binding FilteredOut, Mode=TwoWay}" Value="False">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.Columns>
         <!--removed for brevity-->
    </DataGrid.Columns>
</DataGrid>

Here is the ViewModel to which the DataGrid is binding:

public class Malfunctions : ViewModelBase {
       public ObservableCollection<Model.PartMalfunction> AllPartMalfunctions {
            get;
            private set;
        }
}

Here is the PartMalfunction Model:

public class PartMalfunction {
    private bool _filteredOut = false;
    public bool FilteredOut {
            get {
                return _filteredOut;
            }
            set {
                _filteredOut = value;
            }
        }
    }

Solution

  • Class "PartMalfucntion" needs to implement System.ComponentModel.INotifyPropertyChanged and fire off the PropertyChanged event when FilteredOut's value is changed.

    public class PartMalfunction : System.ComponentModel.INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        #endregion
    
        private bool _filteredOut = false;
        public bool FilteredOut
        {
            get {
                return _filteredOut;
            }
            set {
                _filteredOut = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("FilteredOut"));
            }
        }
    }