Поле со списком WPF в привязке данных к сетке данных / обновление не работает

#.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.