【问题标题】:WPF DataGridComboBoxColumn loses value after focus is lostWPF DataGridComboBoxColumn 失去焦点后失去价值
【发布时间】:2026-01-30 09:40:01
【问题描述】:

在尝试了很多(不起作用)解决方案后,我希望有人可以帮助我。

如果我的DataGrid中选中行的焦点丢失了,ComboBox列的选中值也会丢失。

这是我的 XAML 代码

<Window x:Class="DataGridComboBoxTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:DataGridComboBoxTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <DataGrid Name="dataGrid"></DataGrid>
</Grid>

而她是 CS Code:

using System.Collections.Generic;
using System.Data;
using System.Windows;
using System.Windows.Controls;

namespace DataGridComboBoxTest
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            //Some Sample Data

            DataTable dataTable = new DataTable();
            dataTable.Columns.Add("Name");
            dataTable.Columns.Add("Age");

            DataRow dataRow1 = dataTable.NewRow();
            dataRow1["Name"] = "John";
            dataRow1["Age"] = "33";
            dataTable.Rows.Add(dataRow1);

            DataRow dataRow2 = dataTable.NewRow();
            dataRow2["Name"] = "Emily";
            dataRow2["Age"] = "19";
            dataTable.Rows.Add(dataRow2);

            this.dataGrid.ItemsSource = dataTable.DefaultView;

            //Add ComboBox Column
            Dictionary<string, string> genders = new Dictionary<string, string>();
            genders.Add("f", "female");
            genders.Add("m", "male");

            DataGridComboBoxColumn dgCmbColumn = new DataGridComboBoxColumn();
            dgCmbColumn.Header = "Gender";

            dgCmbColumn.SelectedValuePath = "Key";
            dgCmbColumn.DisplayMemberPath = "Value";
            dgCmbColumn.ItemsSource = genders;


            this.dataGrid.Columns.Add(dgCmbColumn);
        }
    }
}

我尝试了很多使用 Bindings 的解决方案,但对我没有任何效果。

【问题讨论】:

  • 绑定更快更容易,考虑使用虚拟机而不是代码隐藏,然后在您的虚拟机中创建并使用属性“SelectedGender”作为 DatagridComboboxColumn 中的“SelectedItemBinding”。

标签: c# wpf datagridcomboboxcolumn


【解决方案1】:

如果我的DataGrid中选中行的焦点丢失了,ComboBox列的选中值也会丢失。

那是因为您没有将当前选择的值存储在某处。

在您的DataTable 中添加一列:

dataTable.Columns.Add("Gender");

...并设置列的SelectedValueBinding 属性:

dgCmbColumn.SelectedValueBinding = new Binding("Gender");

【讨论】:

  • 但是如果我向下滚动到项目变得不可见并再次向上滚动,值将再次丢失。我猜想绑定不能正常工作。
  • @ToM_ToM:如果您调试代码并查看ItemsSource 的当前值,它是否包含任何“性别”列和值?
  • 是的,它包含一个性别列,但没有任何值。
  • @ToM_ToM: 而ComboBoxItemsSource 还是Dictionary&lt;string, string&gt;
  • 是的,是的。 DataTable dataTable = new DataTable(); dataTable.Columns.Add("Name"); dataTable.Columns.Add("Age"); dataTable.Columns.Add("Gender");Dictionary&lt;string, string&gt; genders = new Dictionary&lt;string, string&gt;(); genders.Add("f", "female"); genders.Add("m", "male");
【解决方案2】:

我建议在 XAML 中定义您的列,因为它比在代码隐藏中更具可读性:

<DataGrid Name="dataGrid" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="Age" Binding="{Binding Age}"/>
        <DataGridComboBoxColumn Header="Gender" SelectedItemBinding="{Binding Gender}" x:Name="myComboBoxColumn"/>
    </DataGrid.Columns>
</DataGrid>

在您的代码隐藏中,不要忘记还为性别定义一个数据列:

dataTable.Columns.Add("Gender");

为了方便操纵性别,让我们创建一个enum

public enum Gender { Male, Female, Other }

最后,将您的专栏的ItemsSource 设置为您的性别列表:

myComboBoxColumn.ItemsSource = new Gender[] { Gender.Male, Gender.Female, Gender.Other };

总代码隐藏变为:

InitializeComponent();

//Some Sample Data

DataTable dataTable = new DataTable();
dataTable.Columns.Add("Name");
dataTable.Columns.Add("Age");
dataTable.Columns.Add("Gender");

DataRow dataRow1 = dataTable.NewRow();
dataRow1["Name"] = "John";
dataRow1["Age"] = "33";
dataTable.Rows.Add(dataRow1);

DataRow dataRow2 = dataTable.NewRow();
dataRow2["Name"] = "Emily";
dataRow2["Age"] = "19";
dataTable.Rows.Add(dataRow2);

this.dataGrid.ItemsSource = dataTable.DefaultView;
myComboBoxColumn.ItemsSource = new Gender[] { Gender.Male, Gender.Female, Gender.Other };

【讨论】: