I have TabControl with two items.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TabControl>
<TabItem Header="Tab1" Content="{Binding}" ContentTemplate="{StaticResource Tab1}"/>
<TabItem Header="Tab2" ContentTemplate="{StaticResource Tab2}"/>
</TabControl>
</Grid>
</Window>
There are DataGrid control in one tabItem of TabControl. DataTemplates of TabItems:
<DataTemplate x:Key="Tab1">
<DataGrid ItemsSource="{Binding Entities}" x:Name="dataGridEx">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="100"/>
<DataGridTemplateColumn Header="Position" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Position}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding Position, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=DataContext.Positions, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
<DataTemplate x:Key="Tab2">
<Grid>
<TextBox Text="Empty tab"></TextBox>
</Grid>
</DataTemplate>
DataContext of MainWindow:
public class MainWindowViewModel
{
public ObservableCollection<Entity> Entities { get; set; }
public List<string> Positions { get { return new List<string>() { "Manager", "Seller" }; } }
public MainWindowViewModel()
{
Entities = new ObservableCollection<Entity>()
{
new Entity() {Name = "John", Position = "Manager"},
new Entity() {Name = "Mark", Position = "Seller"},
new Entity() {Name = "Alice"}
};
}
}
The Entity class:
public class Entity : INotifyPropertyChanged
{
private string _name;
private string _position;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public string Position
{
get { return _position; }
set
{
_position = value;
OnPropertyChanged("Position");
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
#endregion
}
Application is running. I edit the Position column. Then I switch to the 2nd tab and then the 1st tab again. Position value of edited row is deleted.
If I write data directly to tabItems - it works okay
<Grid>
<TabControl>
<TabItem Header="Tab1">...</TabItem>
<TabItem Header="Tab2">...</TabItem>
</TabControl>
</Grid>
But I need to use DataTemplates for tabItems in my solution.
I have some idea.. Using style, not datatemplate inside editing mode
<DataGridComboBoxColumn Header="Position" SelectedItemBinding="{Binding Position, UpdateSourceTrigger=PropertyChanged}">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.Position, ElementName=dataGridEx}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.Variables, ElementName=dataGridEx}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
In this way everything works okay.
But I have custom control like IntelliSense instead of ComboBox. It is requires to use DataGridTemplateColumn with DataTemplates for CellTemplate and CellEditingTemplate. What Should I do in this case? Maybe I need to create custom DataGridComboBoxColumn?
Can you help me with my issue?