Привязка DataGridComboBoxColumn к ObservableCollection

У меня есть класс Устройства с платформой как одно из свойств:

public partial class DevicesCollection : ObservableCollection<Device>
{
    public DevicesCollection() : base()
    { }
}

public partial class Device : INotifyPropertyChanged
{
    private string hostIP;
    private string password;
    private int platform;
    private string status = "";
    private int loop = 1;

    public Device() { }

    public Device(string ip, string pswd, int tp)
    {
        HostIP    = ip;
        Password  = pswd;
        Platform  = tp;
        Status    = "Disconnected";
        Loop = 1;
    }        

А также у меня есть класс Platform:

public partial class PlatformsCollection : ObservableCollection<Platform>
{
    public PlatformsCollection()
        : base()
    {
        Add(new Platform(1, "iOS"));
        Add(new Platform(2, "Android"));
        Add(new Platform(3, "Windows"));
        Add(new Platform(4, "Blackberry"));
    }
}

public partial class Platform : INotifyPropertyChanged
{
    private string platformName;
    private int platformId;

    public Platform(int id, string name)
    {
        PlatformName = name;
        PlatformId = id;
    }
....

У меня есть DataGrid, который привязан к классу Devices, и один из столбцов - это ComboBox Platform, которую я пытаюсь привязать к классу Platform:

<DataGridComboBoxColumn x:Name="platform" Header="Platform" CanUserResize="False"
                        ItemsSource="{Binding Platform}"
                        SelectedValueBinding="{Binding Path=Platform.PlatformId}"
                        SelectedValuePath="PlatformId"
                        DisplayMemberPath="PlatformName" Width="100">
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding Path=Platform.PlatformName}" />
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
</DataGridComboBoxColumn>

Я вижу выпадающее меню со значениями, но после выбора любого значения, когда я пытаюсь получить DataGrid.ItemsSource столбец, платформа пуста. Что я делаю не так? Я попытался изменить столбец на шаблон с выпадающим списком внутри - тот же результат. Буду признателен за любую помощь или, по крайней мере, за направление, в котором можно покопаться.


person Dmitry Z    schedule 30.04.2013    source источник
comment
У меня нет большого опыта работы с DataGridComboBoxColumn, но ItemsSource должен быть привязан к набору платформ вместо одного выбранного устройства Platform. Также ознакомьтесь с некоторыми известными предостережениями в следующих вопросах: Binding DataGridComboBoxColumn и Как привязать коллекцию к WPF: DataGridComboBoxColumn   -  person Sphinxxx    schedule 01.05.2013


Ответы (2)


Вы пытаетесь привязать свойство DataGridComboBoxColumn ItemsSource к ObservableCollection (PlatformsCollection) или к свойству (Platform)?

У вас должно получиться что-то вроде ..

<DataGridComboBoxColumn Header="Platform" ItemsSource="{Binding PlatformsCollection}"
    SelectedValue="{Binding SelectedPlatform}" DisplayMemberPath="PlatformName"/>

Вам нужно будет добавить в свою модель еще одного члена под названием SelectedPlatform, который будет хранить / обновлять каждый раз, когда пользователь меняет выбранную платформу.

Кроме того, вы можете рассмотреть возможность использования комбинации _5 _ / _ 6_ с DataGridTemplateColumn для этого, что выглядит немного лучше. Пользователю предоставляется только текстовое поле, если он не щелкнет ячейку, в которой появится поле со списком.

Разметка для этого будет примерно такой:

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding SelectedPlatform.PlatformName}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding PlatformsCollection}" 
                SelectedValue="{Binding SelectedPlatform}" 
                DisplayMemberPath="PlatformName"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn

Надеюсь, это поможет. Дайте знать, если у вас появятся вопросы.

person Justin    schedule 30.04.2013
comment
Вы правы - я пытался привязать Property (Platfrom) - привязка к PlatformsCollection - недавнее изменение - когда я понял, что привязка к Platform не работает. SelectedPlatform должен быть классом Platform? Прошу прощения, если вопросы глупые - я новичок в WPF и разработке .NET - в общем, я разработчик PHP, которому нужна помощь :) Что касается CellTemplate - это выглядит действительно элегантным решением, но Я должен использовать этот столбец в дополнение к существующему столбцу со списком или вместо? - person Dmitry Z; 01.05.2013
comment
Честно говоря, мне не нужно использовать платформу как класс - все, что мне нужно, это платформа для устройства из списка из 4 пунктов. Есть ли способ создать его без всех этих уловок - какой-то жестко запрограммированный список элементов, который генерирует выпадающее поле со списком? - person Dmitry Z; 01.05.2013
comment
Ой, попался. Да, вы можете просто добавить платформу сложного типа в класс своего устройства и установить атрибут SelectedValue в поле со списком равным Device.Platform. - person Justin; 01.05.2013

Если ваши платформы являются общими для всех объектов, вы можете сделать свойство платформ статическим, и ваш xaml будет использовать его, как показано ниже:

<DataGridComboBoxColumn
    Header="Role"
    SelectedValueBinding="{Binding Role}"
    ItemsSource="{Binding Source={x:Static local:ProjectsDataContext.Roles}}"
    DisplayMemberPath="Name"/>

Надеюсь, это поможет.

person George Lanetz    schedule 29.11.2015