如何在 WPF 中切换单个 DataGridRow 的可见性?

How to toggle visibility of a single DataGridRow in WPF?

目标

我打算创建一个按钮来触发所选行 RowDetailsTemplate 可见性。

问题

我有点设法做到了,但是在我的按钮上单击.. 它显示 RowDetailsTemplates 每条记录。我需要它来显示选定的行,而不是全部。

崩溃

可见

问题

如何只触发选定行的可见状态?

代码

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>

查看模型

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));
    }
}

您不能使用单个视图模型的单个 属性 来切换每一行的可见性。

您应该在行级别添加一个 IsDetailsVisibile 属性,即在 IEnumerable<T> ItemsSourceDataGrid 中的数据对象 T =]:

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>