0

Goal

I am aiming to create a button that triggers selected row RowDetailsTemplate visibility.

Problem

I somewhat managed to do it, but on my button click.. it displays RowDetailsTemplates for every single record. I need it to display the selected row, not all.

Collapsed

enter image description here

Visible

enter image description here

Question

How can I only trigger the selected row visibility state?

Code

XAML

<DataGrid ItemsSource="..." SelectedItem="..." IsReadOnly="True">
    
    <DataGrid.Columns>
        <DataGridTextColumn Header="Product Code" Binding="{Binding ProductCode}" />
        <DataGridTemplateColumn Header="Actions">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Button Content="Edit" Command="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.TriggerVisibility  }" />
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>

    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <StackPanel Background="Orange">
                <TextBlock Text="Test" />
            </StackPanel>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>

    <DataGrid.RowStyle>
        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="DetailsVisibility" Value="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.IsVisible}" />
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

View Model

public ICommand TriggerVisibility { get; }
private void GetVisibleCondition()
{
    if(IsVisible == Visibility.Visible)
    {
        IsVisible = Visibility.Collapsed;
    }
    else if(IsVisible == Visibility.Collapsed)
    {
        IsVisible = Visibility.Visible;
    }
}

private Visibility _isVisible = Visibility.Collapsed;

public Visibility IsVisible
{
    get { return _isVisible; }
    set
    {
        _isVisible = value;
        OnPropertyChanged(nameof(IsVisible));
    }
}
Eduards
  • 1,734
  • 2
  • 12
  • 37
  • https://stackoverflow.com/questions/3829137/i-need-the-expand-collapse-for-rowdetailstemplate – ASh May 06 '21 at 11:39

1 Answers1

1

You cannot use a single property of a single view model to toggle the visibility of each individual row.

You should add an IsDetailsVisibile property at row level, i.e. to your data object T in the IEnumerable<T> ItemsSource of the DataGrid:

public class Product : INotifyPropertyChanged
{
    public Product()
    {
        TriggerVisibility = new RelayCommand2(() => IsDetailsVisibile = !IsDetailsVisibile);
    }

    public string ProductCode { get; set; }

    public ICommand TriggerVisibility { get; }

    private bool _isDetailsVisibile;
    public bool IsDetailsVisibile
    {
        get { return _isDetailsVisibile; }
        set { _isDetailsVisibile = value; NotifyPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public class RelayCommand : ICommand
{
    private readonly Action _execute;
    public RelayCommand(Action execute) => _execute = execute;
    public event EventHandler CanExecuteChanged;
    public bool CanExecute(Object parameter) => true;
    public void Execute(Object parameter) => _execute();
}

XAML:

<DataGrid.Columns>
    <DataGridTextColumn Header="Product Code" Binding="{Binding ProductCode}" />
    <DataGridTemplateColumn Header="Actions">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Button Content="Edit" Command="{Binding TriggerVisibility}" />
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <StackPanel Background="Orange">
            <TextBlock Text="Test" />
        </StackPanel>
    </DataTemplate>
</DataGrid.RowDetailsTemplate>

<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Style.Resources>
            <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        </Style.Resources>
        <Setter Property="DetailsVisibility" Value="{Binding IsDetailsVisibile, 
             Converter={StaticResource BooleanToVisibilityConverter}}" />
    </Style>
</DataGrid.RowStyle>
mm8
  • 163,881
  • 10
  • 57
  • 88