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

WPF MVVM入门:求DataGrid中使用ComboBox的简单实现示例

WPF DataGrid中嵌入ComboBox最简MVVM实现示例

1. 定义基础类

// 下拉框选项实体类
public class OptionItem
{
    public int Id { get; set; }
    public string DisplayName { get; set; }
}

// DataGrid行绑定的实体类,没有CommunityToolkit.Mvvm的话自行实现INotifyPropertyChanged即可
public class DataGridRowModel : ObservableObject
{
    private string _itemName;
    private int _selectedOptionId;

    public string ItemName
    {
        get => _itemName;
        set => SetProperty(ref _itemName, value);
    }

    public int SelectedOptionId
    {
        get => _selectedOptionId;
        set => SetProperty(ref _selectedOptionId, value);
    }
}

2. 编写ViewModel

public class MainViewModel : ObservableObject
{
    // DataGrid绑定的行数据源
    public ObservableCollection<DataGridRowModel> GridData { get; set; } = new();
    // 所有行ComboBox共用的选项列表,无需每行重复存储
    public List<OptionItem> ComboBoxOptions { get; set; } = new();

    public MainViewModel()
    {
        // 初始化下拉选项
        ComboBoxOptions.AddRange(new List<OptionItem>
        {
            new OptionItem { Id = 1, DisplayName = "选项1" },
            new OptionItem { Id = 2, DisplayName = "选项2" },
            new OptionItem { Id = 3, DisplayName = "选项3" }
        });

        // 初始化测试行数据
        GridData.Add(new DataGridRowModel { ItemName = "测试项1", SelectedOptionId = 1 });
        GridData.Add(new DataGridRowModel { ItemName = "测试项2", SelectedOptionId = 2 });
    }
}

3. XAML界面代码

重点注意ComboBox的数据源绑定,需要通过RelativeSource找到父级ViewModel的选项列表:

<Window x:Class="DataGridComboBoxDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataGridComboBoxDemo"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid Margin="10">
        <DataGrid ItemsSource="{Binding GridData}" AutoGenerateColumns="False" CanUserAddRows="True">
            <DataGrid.Columns>
                <!-- 普通文本列 -->
                <DataGridTextColumn Header="项名称" Binding="{Binding ItemName}" Width="*"/>
                <!-- 下拉框列 -->
                <DataGridTemplateColumn Header="选择项" Width="*">
                    <!-- 非编辑状态显示模板,不需要区分状态可删除,直接把ComboBox写在CellTemplate里即可 -->
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding SelectedOptionId, Converter={StaticResource IdToNameConverter}, ConverterParameter={Binding DataContext.ComboBoxOptions, RelativeSource={RelativeSource AncestorType=Window}}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <!-- 编辑状态下拉框模板 -->
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <ComboBox 
                                ItemsSource="{Binding DataContext.ComboBoxOptions, RelativeSource={RelativeSource AncestorType=Window}}"
                                DisplayMemberPath="DisplayName"
                                SelectedValuePath="Id"
                                SelectedValue="{Binding SelectedOptionId, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

新手避坑提示

如果不想写值转换器,可以直接在DataGridRowModel里存储选中的OptionItem对象,ComboBox直接绑定SelectedItem即可,代码更简洁:

  • 行模型新增属性public OptionItem SelectedOption { get; set; }
  • ComboBox删除SelectedValuePath和SelectedValue,改为SelectedItem="{Binding SelectedOption}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:39:03