Search code examples
c#wpfcomboboxdatagriddatatemplate

Datagrid combobox disappearing content + autocomplete


I've been trying to solve this problem since yesterday but without any success (googling). I have a combobox in a DataGridTemplateColumn and when I select something and then click another cell, the content of combobox disappears, but when clicked again in stays. When scrolling down the datagrid, the situation is similar.

I've tried almost everything what I've found on the net but without any success. I do not understand why it happens.

When I switch to a DataGridComboboxColumn, everything works well, but I cannot implement a searchable (autocomplete) combobox in this situation.

My combobox in xaml looks like this:

<DataGrid ItemsSource="{Binding ListOfCars}"
          SelectedItem="{Binding SelectedCar, Mode=TwoWay}"               
    <DataGridTemplateColumn Header="Type">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox
                    Width="150"
                    IsEditable="True"
                    IsDropDownOpen="False"
                    ItemsSource="{Binding Source={StaticResource TypeLists}}"
                    DisplayMemberPath="Type"
                    SelectedValuePath="IDType"
                    SelectedItem="{Binding SelectedType}"                              
                    SelectedValue="{Binding IDType, 
                                            Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                    IsReadOnly="False"
                    IsSynchronizedWithCurrentItem="False">
                </ComboBox>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid>

SelectedCar is of type Car, ListOfCars is of type List<Car> SelectedValue (IDType) is a property in the Car class.

I would like to achieve 2 things:

  1. When selected, an item in the combobox stays even though I click on other cell.
  2. Is there any easy way to implement autocomplete combobox? (I tried with DotNetKit.Wpf.AutoCompleteComboBox but outside datagrid it works like a charm but inside situation is the same as with combobox...)

Solution

  • Regarding first question, I replicated your case, I did a few changes. It works fine for me (Win10 VS pro 2019 .Net 4.7.2). Hopefully you find your answer somewhere there.

    I created your classes

    public class Car
    {
        public int IDType { get; set; }
    }
    
    public class Type
    {
        public string Name { get; set; }
        public int IDType { get; set; }
    
    }
    

    I created a view model with some samples

    class ViewModel
    {
        public List<Car> ListOfCars { get; set; }
        public Car SelectedCar { get; set; }
        public List<Type> TypeLists { get; set; }
    
    
        public ViewModel()
        {
            // Add five cars
            ListOfCars = new List<Car>();
            for (int i = 0; i < 5; i++)
            {
                ListOfCars.Add(new Car());
            }
    
            // Add three types: type0, type1, type2
            TypeLists = new List<Type>();
            for (int i = 0; i < 3; i++)
            {
                TypeLists.Add(new Type() { Name = $"type{i}", IDType = i });
            }
        }
    }
    

    For View, I used main window

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ViewModel();
        }
    }
    

    I added datagrid in Main Window XAML with some changes to go with my view model. If using UserControl, in the code below change AncestorType to UserControl.

    <DataGrid 
            ItemsSource="{Binding ListOfCars}"
            SelectedItem="{Binding SelectedCar, Mode=TwoWay}" >
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Type">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox
                                Width="150"
                                IsEditable="True"
                                IsDropDownOpen="False"
                                ItemsSource="{Binding 
                                    Path = DataContext.TypeLists, 
                                    RelativeSource={RelativeSource FindAncestor, 
                                    AncestorType=Window}}"
                                DisplayMemberPath="Name"
                                SelectedValuePath="IDType"                                                           
                                SelectedValue="{Binding IDType, 
                                            Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                IsReadOnly="False"
                                IsSynchronizedWithCurrentItem="False">
                            </ComboBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    

    I get below table, left column is comboxes bound to TypeLists, right column is Car IDType auto generated.

    enter image description here

    I changed some combo boxes and then scrolled, everything in place. enter image description here

    Based on experience data disappears from window/usercontrol for two reasons: wrong binding and null injection into properties.

    When wrong binding, data is not stored and any refresh of window they will be gone. In debug mode check the output window of VS, it gives you information if there is corrupt bindings.

    Sometimes a null is injected into a property when navigating pages. This can be avoided by adding the line below in the setter of problematic properties:

    if (value==null) return