How can I use a collection on the data item row of my Windows Community Template datagrid as the Itemsource for a ComboBox column on the same row?

随声附和 提交于 2021-02-11 14:56:33

问题


How can I bind the ItemsSource of a Combobox column to a collection that is a sub-property of a property on the same row? In other words, the DataGrid is bound to a collection of items of a class the contains Property1 and Property2. So the DataGrid has two columns, Property1 and Property2. Property1 has a sub-property that is an Observable Collection. The column for Property2 is a Combobox column that should use Property1's Observable Collection as its ItemsSource.

I'm loading the grid's source data via EFCore. I have made sure to use ".Include" to be sure Property1's Observable Collection is getting loaded into memory. I'm wondering if the issue is that the UI is not made aware that Property1's Observable Collection has been updated when it is loaded from the database? If that's the issue, how could I correct this?

I need this collection to serve as the ItemsSource for the Property2 column shown below. I've tried using relative source to get the datacontext of the grid, but it is not working.

<wct:DataGridComboBoxColumn  Binding="{Binding Property2, Mode=TwoWay}"                                                
                             ItemsSource="{Binding Path=DataContext.Property1.MyCollection, 
                             RelativeSource={RelativeSource TemplatedParent}, 
                             Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">

I've also tried this:

ItemsSource="{Binding ElementName=grid, 
              Path=DataContext.Property1.MyCollection}"

Thanks.


回答1:


Derive official processing method, the better way is set DataGridComboBoxColumn in the code behind. Give DataGridComboBoxColumn a tag name and find the column with tag like the following then set DataGridComboBoxColumn ItemsSource.

MyCollection = new List<string> { "DD", "FF", "CC" };           
var comboBoxColumn = MyDataGrid.Columns.FirstOrDefault(x => x.Tag.Equals("Link")) as DataGridComboBoxColumn;
if (comboBoxColumn != null)
{
    comboBoxColumn.ItemsSource = MyCollection;
}
MyDataGrid.ItemsSource = items;

Xaml Code

<controls:DataGridComboBoxColumn
    Width="*"
    Binding="{Binding p2}"
    Header="Link"   
    Tag="Link"
    />

DataGridComboBoxColumn ItemsSource property could not access data source sub property directly, so we need make a list property for the Page class that uses to store Property1.MyCollection. If you already make MyCollection propety for the Page class, you could also use x:bind to access like the following.

<controls:DataGridComboBoxColumn 
    Width="*"
    Binding="{Binding p2}"
    Header="Link"   
    ItemsSource="{x:Bind MyCollection,Mode=OneWay}"
    Tag="Link"
    />

Update

If the Property1.MyCollection is not constant list, you could try to use DataGridTemplateColumn custom column cell and bind the data source like the following

<controls:DataGridTemplateColumn>
    <controls:DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox
                HorizontalAlignment="Stretch"
                VerticalAlignment="Center"
                ItemsSource="{Binding p1.Mycollection, Mode=OneWay}"
                SelectionChanged="ComboBox_SelectionChanged"
                />
        </DataTemplate>
    </controls:DataGridTemplateColumn.CellEditingTemplate>
    <controls:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock
                Margin="10"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Center"
                Text="{Binding p2, Mode=OneWay}"
                />
        </DataTemplate>
    </controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>

Code behind

public class P1
{
    public string Name { get; set; }
    public List<string> Mycollection { get; set; }
}

public class ITPP
{
    public P1 p1 { get; set; }
    public string p2 { get; set; }
}
private void CreateDataSource()
{
    items = new List<ITPP>();
    items.Add(new ITPP { p1 = new P1 { Name = "FirstP1", Mycollection = new List<string>() { "AA", "BB", "CC", "DD" } }, p2 = "CC" });
    items.Add(new ITPP { p1 = new P1 { Name = "SecondP1", Mycollection = new List<string>() { "EE", "FF", "GG", "HH" } }, p2 = "HH" });
    items.Add(new ITPP { p1 = new P1 { Name = "ThirdP1", Mycollection = new List<string>() { "II", "JJ", "KK", "LL" } }, p2 = "LL" });
    MyDataGrid.ItemsSource = items;
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var mycombobox = sender as ComboBox;
    var p1collection = mycombobox.ItemsSource;
    foreach (var item in items)
    {
        if (item.p1.Mycollection == p1collection)
        {
            item.p2 = mycombobox.SelectedItem as string;
        }
    }
}


来源:https://stackoverflow.com/questions/60837543/how-can-i-use-a-collection-on-the-data-item-row-of-my-windows-community-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!