WPF DataGridComboBoxColumn теряет значение после потери фокуса

попробовав множество (не работающих) решений, я надеюсь, что кто-то может мне помочь.

Если фокус выбранной строки в моем 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:

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, но у меня ничего не работает.


person ToM_ToM    schedule 02.07.2020    source источник
comment
Привязка выполняется намного быстрее и проще. Рассмотрите возможность использования виртуальной машины вместо кода программной части, а затем создайте и используйте свойство «SelectedGender» в своей виртуальной машине в качестве «SelectedItemBinding» в DatagridComboboxColumn.   -  person Rufw91    schedule 02.07.2020


Ответы (2)


Если фокус выбранной строки в моем DataGrid будет потерян, выбранное значение столбца ComboBox также будет потеряно.

Это потому, что вы нигде не сохраняете текущее выбранное значение.

Добавьте столбец в DataTable:

dataTable.Columns.Add("Gender");

... и установите свойство SelectedValueBinding столбца:

dgCmbColumn.SelectedValueBinding = new Binding("Gender");
person mm8    schedule 02.07.2020
comment
Но если я прокручиваю вниз так далеко, что элементы становятся невидимыми, и снова прокручиваю вверх, значения снова будут потеряны. Я предполагаю, что привязка не работает должным образом. - person ToM_ToM; 02.07.2020
comment
@ToM_ToM: Если вы отлаживаете свой код и смотрите на текущее значение ItemsSource, содержит ли он какой-либо столбец и значения Gender? - person mm8; 03.07.2020
comment
Да. Он содержит столбец «Пол», но без каких-либо значений. - person ToM_ToM; 03.07.2020
comment
@ToM_ToM: И ItemsSource из ComboBox все еще Dictionary<string, string>? - person mm8; 03.07.2020
comment
Да, это так. DataTable dataTable = new DataTable(); dataTable.Columns.Add("Name"); dataTable.Columns.Add("Age"); dataTable.Columns.Add("Gender"); Dictionary<string, string> genders = new Dictionary<string, string>(); genders.Add("f", "female"); genders.Add("m", "male"); - person ToM_ToM; 03.07.2020
comment
@ToM_ToM: Не могли бы вы отредактировать свой вопрос тем, что у вас есть сейчас? - person mm8; 06.07.2020

Я предлагаю определить ваши столбцы в 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 };
person Corentin Pane    schedule 02.07.2020