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:
DotNetKit.Wpf.AutoCompleteComboBox
but outside datagrid it works like a charm but inside situation is the same as with combobox...)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.
I changed some combo boxes and then scrolled, everything in place.
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