You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVVM模式下如何通过命令或转换器绑定RowDetailsVisibilityMode到ViewModel的bool变量?

MVVM模式下DataGrid行详情可见性的命令式控制实现

核心思路

通过IValueConverter将ViewModel中的布尔变量转换为Visibility枚举,配合DataGrid行样式绑定实现命令控制行详情显示,全程不使用事件,符合MVVM规范。

步骤1:实现布尔值转Visibility转换器

创建转换器类,完成bool与Visibility的双向转换:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is bool boolValue && boolValue ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is Visibility visibility && visibility == Visibility.Visible;
    }
}

步骤2:在XAML中配置转换器与绑定

  1. 在窗口/页面资源中声明转换器:
<Window.Resources>
    <local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
</Window.Resources>
  1. 配置DataGrid的行样式,绑定行详情可见性到ViewModel的布尔变量:
<DataGrid>
    <!-- 行样式绑定:控制选中行的详情可见性 -->
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="DetailsVisibility" 
                    Value="{Binding DataContext.VisabilityRowDetailsTemplate, 
                            RelativeSource={RelativeSource AncestorType=DataGrid}, 
                            Converter={StaticResource BoolToVisibilityConverter}}"/>
        </Style>
    </DataGrid.RowStyle>

    <!-- 你的行详情模板 -->
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Foreground="White" Margin="16" Text="{Binding ContolPageName, Mode=TwoWay}"/>
            </Grid>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>

    <!-- 触发命令的按钮 -->
    <Button Content="切换行详情显示" Command="{Binding EditDataGridFormatViewCommand}"/>
</DataGrid>

步骤3:完善ViewModel实现

确保ViewModel实现INotifyPropertyChanged,并正确声明命令与绑定属性:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

public class YourViewModel : INotifyPropertyChanged
{
    private bool _visabilityRowDetailsTemplate;
    public bool VisabilityRowDetailsTemplate
    {
        get => _visabilityRowDetailsTemplate;
        set
        {
            _visabilityRowDetailsTemplate = value;
            OnPropertyChanged();
        }
    }

    public ICommand EditDataGridFormatViewCommand { get; }
    public object CurrentChildsView { get; set; }
    public string ContolPageName { get; set; }

    public YourViewModel()
    {
        EditDataGridFormatViewCommand = new RelayCommand(ExecuteEditDataGridFormatViewCommand);
        // 默认选中行时详情折叠
        VisabilityRowDetailsTemplate = false;
    }

    public void ExecuteEditDataGridFormatViewCommand(object obj)
    {
        if (!VisabilityRowDetailsTemplate)
        {
            CurrentChildsView = new DataGridFormatViewModel();
            ContolPageName = "PANEL";
            VisabilityRowDetailsTemplate = true;
        }
        else
        {
            VisabilityRowDetailsTemplate = false;
        }
    }

    #region INotifyPropertyChanged实现
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

// 通用RelayCommand实现
public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add => CommandManager.RequerySuggested += value;
        remove => CommandManager.RequerySuggested -= value;
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute ?? throw new ArgumentNullException(nameof(execute));
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true;

    public void Execute(object parameter) => _execute(parameter);
}

说明

  • 默认状态下VisabilityRowDetailsTemplate为false,选中行的详情区域保持折叠;
  • 点击按钮触发命令后,切换布尔变量值,转换器自动将其转为Visibility.Visible,显示行详情;
  • 通过RelativeSource绑定到DataGrid的DataContext,确保行样式能正确访问ViewModel中的属性。

内容的提问来源于stack exchange,提问作者Anna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:53:19