C#/WPF:将 Datagrid 中的 Combobox ItemSource 绑定到 DataContext 之外的元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1497113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:07:41  来源:igfitidea点击:

C#/WPF: Binding Combobox ItemSource in Datagrid to element outside of the DataContext

c#wpfdatagridbindingcombobox

提问by Joseph jun. Melettukunnel

I'd like to do following:

我想做以下事情:

public List<Users> PreLoadedUserList { get; set; }
public List<RowEntries> SomeDataRowList { get; set; }

public class Users
{
    public int Age { get; set; }
    public string Name { get; set; }
}
public class SomeDataRowList 
{
    public int UserAge { get; set;
}

Now my (WPF Toolkit) DataGrid looks like this:

现在我的(WPF 工具包)DataGrid 看起来像这样:

<my:DataGrid AutoGenerateColumns="False" MinHeight="200" 
             ItemsSource="{Binding Path=SomeDataRowList}">
    <my:DataGridComboBoxColumn Header="Age" 
                               ItemsSource="{Binding Path=PreLoadedUserList}" 
                               DisplayMemberPath="Name" 
                               SelectedValueBinding="{Binding Path=UserAge}"/>

</my:DataGrid>

Now my problem is, that PreLoadedUserList is outside of the ItemSource (SomeDataRowList) and I don't know how to bind to something outside of it. What I actually want it: - Display in the ComboBox PreLoadedUserList - Set the Value of (RowEntries) SelectedItem.UserAge to the Value of the selected ComboboxItem.Age

现在我的问题是,PreLoadedUserList 在 ItemSource (SomeDataRowList) 之外,我不知道如何绑定到它之外的东西。我真正想要的是: - 在 ComboBox PreLoadedUserList 中显示 - 将 (RowEntries) SelectedItem.UserAge 的值设置为所选 ComboboxItem.Age 的值

Let me know if my explanation is too weird :-)

如果我的解释太奇怪,请告诉我:-)

Thank you, Cheers

谢谢,干杯

采纳答案by Joseph jun. Melettukunnel

Here we go :-)

开始了 :-)

<my:DataGridTemplateColumn Header="SomeHeader">
    <my:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox SelectedValuePath="UserAge" 
                SelectedValue="{Binding Age}" 
                DisplayMemberPath="Name" 
                ItemsSource="{Binding Path=DataContext.PreLoadedUserList, 
                    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
                IsReadOnly="True" Background="White" />
        </DataTemplate>
    </my:DataGridTemplateColumn.CellTemplate>
</my:DataGridTemplateColumn>

Hope this can help someone else too.

希望这也可以帮助其他人。

Cheers

干杯

回答by Rich

If RowEntries is a custom class, just give it a reference to the PreLoadedUserList. Then, each instance has a pointer to it and you can use it in your binding.

如果 RowEntries 是一个自定义类,只需给它一个对 PreLoadedUserList 的引用。然后,每个实例都有一个指向它的指针,您可以在绑定中使用它。

Just a suggestion, class names like Users and RowEntries suggest that they are collections but your usage looks like they're the item not the collection. I'd use singular names to avoid any confusion. I'd do something like this

只是一个建议,像 Users 和 RowEntries 这样的类名表明它们是集合,但您的用法看起来像是项目而不是集合。我会使用单数名称来避免任何混淆。我会做这样的事情

public List<User> PreLoadedUserList { get; set; }
public List<RowEntry> SomeDataRowList { get; set; }

public class User
{
    public int Age { get; set; }
    public string Name { get; set; }
}
public class RowEntry 
{
    public int UserAge { get; set; }
    public List<User> PreLoadedUserList { get; set; }
}

// at the point where both PreLoadedUserList is instantiated
// and SomeDataRowList is populated
SomeDataRowList.ForEach(row => row.PreLoadedUserList = PreLoadedUserList);