WPF — ошибка привязки в DataGridComboboxColumn

Мне нужно использовать DataGridComboboxColumn в моем dataGrid. Но наблюдаемая коллекция, которую я собираюсь привязать к своей сетке данных, не статична?

необходимо, чтобы эта коллекция Observale была статической, поскольку сетка данных содержит DataGridComboboxColumn.

То, что я собираюсь привязать к столбцу DataGridCombobox, — это еще одна коллекция, содержащаяся в классе объектов, находящихся в наблюдаемой коллекции, о которой я упоминал выше. Это первый раз, когда я использую столбец DataGridCombobox. Любое объяснение будет высоко оценено.

<DataGrid ItemSource="{Binding SomeData}">
    <DataGrid.Columns>
        <DataGridTemplateColumn DisplayMemberPath="FirstName" />
        <DataGridTemplateColumn DisplayMemberPath="LastName"  />
        <DataGridComboboxColumn ItemSource={Binding SomeOtherListContainedInSomeDataAbove}" />
    </DataGrid.Columns>
<DataGrid>

Но это генерирует ошибки привязки и говорит, что SomeOtherListContainedInSomeDataAbove не может быть найден.

Пожалуйста, помогите.


person nidarshani fernando    schedule 08.05.2015    source источник
comment
Вероятно, вам нужно установить DataContext   -  person Galma88    schedule 08.05.2015
comment
Где находится SomeOtherListContainedInSomeDataAbove? Это во ViewModel?   -  person Ayyappan Subramanian    schedule 08.05.2015
comment
Да, кажется, вам нужно дать больше информации. Что за DataContext, что где живет и т.д...   -  person Noctis    schedule 08.05.2015


Ответы (2)


DataGridComboboxColumn не участвует в логическом дереве, и, следовательно, трудно выполнить привязку для его ItemsSource напрямую. Но DataGridCell является частью логического дерева. Вы можете создать стиль элемента и попытаться связать свою коллекцию. В приведенном ниже примере я дал два подхода, используя DataGridComboBoxColumn и DatagridTemplateColumn. Я предполагаю, что вы используете MVVM.

<DataGrid ItemsSource="{Binding DataGrdList}" AutoGenerateColumns="False">            
        <DataGrid.Columns>
            <DataGridComboBoxColumn SelectedItemBinding="{Binding DataTypeName}"  Header="Combo">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.DataTypeList}"/>
                        <Setter Property="IsReadOnly" Value="True"/>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.DataTypeList}"/>
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
            <DataGridTemplateColumn Header="Template">
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox SelectedValue="{Binding Path=DataTypeName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DataContext.DataTypeList}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=DataTypeName, UpdateSourceTrigger=PropertyChanged}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>

    </DataGrid>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainViewModel();
    }
}

public class MainViewModel
{
    private ObservableCollection<string> myVar = new ObservableCollection<string>();

    public ObservableCollection<string> DataTypeList
    {
        get { return myVar; }
        set { myVar = value; }
    }

    private ObservableCollection<DataType1> myVar1 = new ObservableCollection<DataType1>();

    public ObservableCollection<DataType1> DataGrdList
    {
        get { return myVar1; }
        set { myVar1 = value; }
    }

    public MainViewModel()
    {
        myVar.Add("Int");
        myVar.Add("Bool");
        myVar.Add("String");  
    }   
}

public class DataType1
{
    private string name;

    public string DataTypeName
    {
        get { return name; }
        set { name = value; }
    }  
}
person Ayyappan Subramanian    schedule 08.05.2015
comment
Спасибо, это был правильный ответ для меня, также отличный пример! - person MRK; 12.04.2019
comment
Есть и другой способ, который я нашел здесь: stackoverflow.com/a/37812160/6296708 Этот ответ использует эту статью [[WPF ] КАК ПРИВЯЗАТЬСЯ К ДАННЫМ, ЕСЛИ КОНТЕКСТ ДАННЫХ НЕ НАСЛЕДУЕТСЯ](thomaslevesque.com/2011/03/21/) на тот случай, если кому-то не нравится использовать Template или Style. (для использования класса Freezable) - person MRK; 12.04.2019

Ты пытался :

<DataGridComboboxColumn ItemSource={Binding path=SomeOtherListContainedInSomeDataAbove}"> 

Если вашим контекстом для привязки является SomeData, это должно указывать на правильное свойство)

Из MSDN:

Чтобы заполнить раскрывающийся список, сначала задайте свойство ItemsSource для ComboBox, используя один из следующих параметров.

  • Статический ресурс. Дополнительные сведения см. в разделе Расширение разметки StaticResource.

  • Объект x:Static code. Дополнительные сведения см. в разделе Расширение x:Static Markup.

  • Встроенная коллекция типов ComboBoxItem.

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

Итак, если это не статично, я бы сказал, попробуйте вариант 3 :)

person Noctis    schedule 08.05.2015
comment
Я получаю следующую ошибку, когда делаю это так. Не удается найти управляющий элемент FrameworkElement или FrameworkContentElement для целевого элемента. BindingExpression:Path=SomeOtherListContainedInSomeDataAbove DataItem=null; целевой элемент — DataGridComboBoxColumn (HashCode=51802613); целевое свойство — «ItemsSource» (тип «IEnumerable») - person nidarshani fernando; 08.05.2015