#.net #wpf #data-binding #datagrid #combobox
#.net #wpf #привязка данных #сетка данных #поле со списком #datagrid
Вопрос:
Если я настрою новое приложение WPF в Visual Studio 2010 и добавлю следующий код XAML, откроется таблица данных со списком внутри. Проблема сейчас заключается в том, что изменение значения через поле со списком не распространяется на связанную модель данных. Другими словами: свойство с именем myValue никогда не устанавливается. Это заняло у меня несколько часов, и я понятия не имею, почему это не работает. Также многие подобные темы и предложения не сработали.
Вот XAML. Это всего лишь простое окно, содержащее DataGrid. В DataGrid есть столбец шаблона, в котором заданы CellTemplate и CellEditingTemplate. Оба содержат выпадающий список, который заполнен списком из раздела ресурсов. Поле со списком.Выбранный элемент привязан к MyItem.myValue:
<Window x:Class="DataGridComboBoxExample.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" xmlns:local="clr-namespace:DataGridComboBoxExample">
<Window.Resources>
<local:MyItemList x:Key="ItemList"/>
<DataTemplate x:Key="NotificationModeDataTemplate">
<ComboBox
ItemsSource="{StaticResource ItemList}"
SelectedItem="{Binding Path=MyValue, Mode=OneWay}" />
</DataTemplate>
<DataTemplate x:Key="NotificationModeEditTemplate">
<ComboBox
ItemsSource="{StaticResource ItemList}"
SelectedItem="{Binding Path=MyValue, Mode=TwoWay}" />
</DataTemplate>
</Window.Resources>
<Grid>
<DataGrid x:Name="myDataGrid" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn
Header="Test" Width="100"
CellTemplate="{StaticResource NotificationModeDataTemplate}"
CellEditingTemplate="{StaticResource NotificationModeEditTemplate}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Вот код. Он содержит главное окно ctor, которое просто устанавливает DataContext. MyItem — это модель данных строки, поддерживающая INotifyPropertyChanged. MyItemList — это список вариантов, привязанных к ComboBox.ItemsSource.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
myDataGrid.ItemsSource = new List<MyItem>
{
new MyItem { MyValue = "i0" },
new MyItem { MyValue = "i1" },
new MyItem { MyValue = "i0" },
};
}
}
public class MyItem : INotifyPropertyChanged
{
public string MyValue
{
get { return myValue; }
set
{
myValue = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("MyValue"));
}
}
}
private string myValue;
public event PropertyChangedEventHandler PropertyChanged;
}
public class MyItemList : List<string>
{
public MyItemList() { Add("i0"); Add("i1"); Add("i2"); }
}
Ответ №1:
Я подозреваю, что вам нужно будет заставить привязку SelectedItem обновить исходный код в PropertyChanged, чтобы это сработало.
SelectedItem=»{Путь привязки=myValue, Mode= TwoWay, UpdateSourceTrigger=PropertyChanged}»
Я бы сделал так, чтобы CellTemplate и CellEditingTemplate ссылались на ваш шаблон редактирования во время отладки этого, чтобы исключить другой, не относящийся к делу шаблон, пока вы с ним не разберетесь.
Комментарии:
1. Я только что протестировал это, и у меня это сработало. Я заставил CellTemplate и CellEditingTemplate ссылаться на шаблон редактирования и добавил UpdateSourceTrigger=PropertyChanged. Когда я выбираю элемент в выпадающем списке, вызывается параметр установки myValue. Я тестирую .NET 4.0 с установленным пакетом обновления 2010.1.
2. Почему это на самом деле работает? Если я перемещу то же самое
ComboBox
за пределы DataGrid (просто в список), это не понадобится для той же viewmodel.