Search code examples
c#wpfexpanderisenabled

Cannot Disable WPF Expander with a Style


I created a style for my Expander control that's supposed to disable the expander if it's value is false, but it does not work at all. My expander is Enabled all the time, no matter if IsCheckedIn is true or false.

<Style x:Key="CollapseIsCheckedInExpander" TargetType="{x:Type Expander}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsCheckedIn}" Value="False">
            <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
    </Style.Triggers>
</Style>  

And here is where I set the style of my expander in my datagrid:

<Expander Expanded="Expander_Expanded" Collapsed="Expander_Expanded" Style="{DynamicResource CollapseIsCheckedInExpander}"/>

I have a property code-behind that's called "IsCheckedIn" and I set the value to true or false based on if the truck I'm checking in is already checked in or not.

Is there something I'm missing?

EDIT:

Here is my class:

public class TruckItems : INotifyPropertyChanged
{        
    bool _isCheckedIn;
    public bool IsCheckedIn
    {
        get { return _isCheckedIn; }
        set
        {
            if (_isCheckedIn != value)
                _isCheckedIn = value;
            OnPropertyChanged("IsCheckedIn");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }        
}

And here is a snipped where I define my IsCheckedIn:

truckItem.TruckCurrentPhase = item.CurrentPhase; //Current value is "Not Started", so the IsCheckedIn value should be false in the code below
truckItem.IsCheckedIn = truckItem.TruckCurrentPhase == "Checked In" ? true : false;

SOLUTION

I found that my issue was using the RowHeaderTemplate. For some reason it did not pick up my bindings but the DataGridTemplateColumn did...

This does not work:

<DataGrid.RowHeaderTemplate>
    <DataTemplate>
        <Expander Expanded="Expander_Expanded" Collapsed="Expander_Expanded" Style="{StaticResource CollapseIsCheckedInExpander}"/>
    </DataTemplate>
</DataGrid.RowHeaderTemplate>

This does work:

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Expander Expanded="Expander_Expanded" Collapsed="Expander_Expanded" Style="{StaticResource CollapseIsCheckedInExpander}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Solution

  • I build up a simple example (using Caliburn Micro for Binding and Notify...). It works fine for me.

    With this you can test the Binding simply. Set the two Breakpoints while your Application is running. If you Change the Checkbox the Breakpoint1 should fire and Breakpoint2 should fire afterwards (I think for two times, to get actual value for the CheckBox and actual value for the Expander IsEnabled). If the breakpoints don't fire you have to check your DataContext (in your original code the DataContext need to be a truckItem not your ViewModel... have you checked this?).

    xaml

     <CheckBox IsChecked="{Binding ExpanderEnable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">Enalble Expander</CheckBox>
     <Expander IsEnabled="{Binding ExpanderEnable, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
         <TextBlock>TestText</TextBlock>
     </Expander>
    

    cs

     private bool _expanderEnable;
    
     public bool ExpanderEnable {
         get 
         { 
             return _expanderEnable; //Breakpoint2
         }
         set {
             if (value == _expanderEnable) return; //BreakPoint1
             _expanderEnable = value;
             OnPropertyChanged();
         }
     }
    
    public event PropertyChangedEventHandler PropertyChanged;
    
    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }