У меня есть TabControl с двумя элементами.
<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>
В одном tabItem TabControl есть элемент управления DataGrid. Шаблоны данных 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>
Контекст данных 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"}
};
}
}
Класс сущности:
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
}
Приложение запущено. Я редактирую столбец «Позиция». Затем я переключаюсь на 2-ю вкладку, а затем снова на 1-ю вкладку. Значение позиции редактируемой строки удаляется.
Если я пишу данные напрямую в tabItems - все работает нормально
<Grid>
<TabControl>
<TabItem Header="Tab1">...</TabItem>
<TabItem Header="Tab2">...</TabItem>
</TabControl>
</Grid>
Но мне нужно использовать DataTemplates для tabItems в моем решении.
У меня есть идея.. Использование стиля, а не шаблона данных в режиме редактирования
<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>
Таким образом, все работает нормально.
Но у меня есть настраиваемый элемент управления, например IntelliSense, вместо ComboBox. Требуется использовать DataGridTemplateColumn с DataTemplates для CellTemplate и CellEditingTemplate. Что мне делать в этом случае? Может быть, мне нужно создать собственный DataGridComboBoxColumn?
Можете ли вы помочь мне с моей проблемой?