0

In my WPF DataGrid, the data is populated from Employee class (shown below). The StateName column in the Employee class is a Combobox inside DataGrid. The Combobox is populated from the State class (shown below). The data is displayed correctly (as shown in image 1 below). But when I select a different state from the combobox (as shown in image 2 below) and move the cursor to the next row of the grid, the newly selected value of the State changes back to the default value. For example, when in the first row I change the combobox value from Iowa to Ohio and move to the cursor to a different row, the value of the State column in first row changes back from Ohio to Iowa. Question: I have not implemented any events yet, but I was wondering why the state column value changes back to the original value after I move the cursor to a different row?

<Window x:Class="WPF_DataGridCombobox.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:WPF_DataGridCombobox"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:StateList x:Key="ListOfStates"/>
    </Window.Resources>
    <Grid>
        <DataGrid x:Name="dgEmplyees" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding  Name}"/>
                <DataGridTemplateColumn Header="State Name">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding StateName}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="cmbState" ItemsSource="{StaticResource ListOfStates}" DisplayMemberPath="StateName" SelectedValuePath="StateCode" IsEditable="False" IsReadOnly="True" />                            
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

When MainWindow is loaded:

enter image description here

Demonstrtion of Combobox to change a State:

enter image description here

Employee.cs:

public class Employee
{
    public int EmployeeId { get; set; }
    public string Name { get; set; }
    public string StateName { get; set; }
}

State.cs:

public class State
{
    public string StateName { get; set; }
    public string StateCode { get; set; }
}

StateList.cs:

public StateList()
{
    Add(new State { StateName = "Iowa", StateCode = "IA" });
    Add(new State { StateName = "Nebraska", StateCode = "NE" });
    Add(new State { StateName = "Ohio", StateCode = "OH" });
    Add(new State { StateName = "Virginia", StateCode = "VA" });
}

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        List<Employee> employees = new List<Employee>();
        employees.Add(new Employee { EmployeeId = 1, Name = "Tom Smith", StateName = "Iowa" });
        employees.Add(new Employee { EmployeeId = 2, Name = "Jane Price", StateName = "Nebraska" });
        employees.Add(new Employee { EmployeeId = 3, Name = "Chris Puin", StateName = "Ohio" });
        employees.Add(new Employee { EmployeeId = 4, Name = "Amber Friedman", StateName = "Virginia" });

        dgEmplyees.ItemsSource = employees;
    }
}
nam
  • 21,967
  • 37
  • 158
  • 332
  • 2
    There is `SelectedValuePath="StateCode"` on the ComboBox, but no `SelectedValue` Binding. How do you expect this to work, i.e. to change anything in the view model? It is also unclear why there is a State type with StateName and StateCode at all. In order to change the StateName of the Employee, just use `SelectedValuePath="StateName" SelectedValue="{Binding StateName}`, where the StateName source property is that of the Employee. – Clemens Aug 24 '20 at 08:04
  • @Clemens Combobox has two values: `StateName` for display, and `StateCode` for selectedValue (a unique value behind Combobox that I will use for another purpose in the code) as explained [here](https://stackoverflow.com/a/3797074/1232087). Did I misunderstand something in the post I linked. Any suggestion/comment? – nam Aug 24 '20 at 14:06
  • 1
    Sure, but StateCode is never used for anything. It's unclear why you have that in the first place. It serves no purpose. The code in the linked answer makes no sense without a SelectedValue Binding. It is incomplete. – Clemens Aug 24 '20 at 14:18
  • @Clemens `code in the linked answer makes no sense without a SelectedValue Binding` Yes, that was the confusion. I will use the `StateCode` later in the app. A minor change to your suggestion worked (thank you) for my need, as follows: `SelectedValuePath="StateCode" SelectedValue="{Binding StateName}"` – nam Aug 24 '20 at 14:28
  • Thus you would be setting the Employee's StateName to a StateCode. – Clemens Aug 24 '20 at 14:30
  • @Clemens Uhm!! I just ran the app and noticed you are correct. I need to do some adjustments because I do need `StateCode` once the `StateName` is selected from the Combobox – nam Aug 24 '20 at 15:25

0 Answers0