【问题标题】:C# WPF - DataGridComboBoxColumn ItemsSourceC# WPF - DataGridComboBoxColumn ItemsSource
【发布时间】:2017-03-21 00:44:20
【问题描述】:

我目前正在努力使用 C# WPF 中的 DataGridComboBoxColumn。

我有类 ToolModel

class ToolModel
{
    public long Id { get; set; }
    public string Number { get; set; }
    public string Name { get; set; }
    public string Coating { get; set; }
    public bool Thread { get; set; }
    public string Kind { get; set; }
    public ToolTypeModel Type { get; set; }
}

和类 ToolTypeModel

public class ToolTypeModel
{
    public long Id { get; set; }
    public string Name { get; set; }
}

数据存储到数据库中并加载到我的 ViewModel 中

class ToolsViewModel
{
    public ObservableCollection<ToolModel> Tools { get; set; }
    public ObservableCollection<ToolTypeModel> ToolTypes { get; set; }

    public ToolsViewModel()
    {
        Tools = new ObservableCollection<ToolModel>(ToolModel.GetTools());
        ToolTypes = new ObservableCollection<ToolTypeModel>(ToolTypeModel.GetToolTypes());
    }
}

我想在 DataGrid 中显示数据并尝试添加 DataGridComboBoxColumn 来为对应的 Tool 选择 ToolType。因此我添加了以下 xaml 定义(这已经是一种解决方法 - 但我能够让它几乎工作的唯一方法):

 <DataGrid x:Name="ToolsDataGrid" ItemsSource="{Binding Tools}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Nummer" Binding="{Binding Number}" />
            <DataGridComboBoxColumn 
                    Header="Typ"
                    SelectedValueBinding="{Binding Type, Mode=TwoWay}" 
                    SelectedValuePath="Id"
                    DisplayMemberPath="Name">

                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.ToolTypes, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.ToolTypes, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>

它显示了 ToolTypes 的所有元素不是我的工具引用的所选元素。

任何想法如何将 ToolTypes 查找到 ComboBoxColumn 并将引用的 Type 显示为选定项?

提前致谢。

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    SelectedValuePath 是将通过SelectedValueBinding 绑定的组合框项的属性的路径。因此,SelectedValueBinding 必须绑定到相同类型的属性。

    <DataGridComboBoxColumn 
        Header="Typ"
        SelectedValueBinding="{Binding Type, Mode=TwoWay}" 
        SelectedValuePath="Id"
        DisplayMemberPath="Name">
    

    如果您有 ToolTypeId 属性,您将使用 SelectedValuePath 绑定到该属性:

    class ToolModel
    {
        public long Id { get; set; }
        public string Number { get; set; }
        public string Name { get; set; }
        public string Coating { get; set; }
        public bool Thread { get; set; }
        public string Kind { get; set; }
    
        //  Like so
        public long ToolTypeId { get; set; }
    
        public ToolTypeModel Type { get; set; }
    }
    

    在 XAML 中:

    <DataGridComboBoxColumn 
        Header="Typ"
        SelectedValueBinding="{Binding ToolTypeId}" 
        SelectedValuePath="Id"
        DisplayMemberPath="Name">
    

    但我认为这不是你想要的。我认为很明显你想在你的Type 属性中获得一个实际的ToolTypeModel 实例。

    所以这应该可以工作(我刚刚测试过)。但是,以汽车为例:重写 Equals() 有点粗略,因为它会更改该类的 C# =!= 运算符的语义,这可能会咬你一口。

    public class ToolTypeModel
    {
        public long Id { get; set; }
        public string Name { get; set; }
    
        public override bool Equals(object obj)
        {
            return (obj is ToolTypeModel)
                        ? (obj as ToolTypeModel).Id == Id
                        : false;
        }
    
        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }
    }
    

    XAML:

    <DataGridComboBoxColumn
        Header="Type"
        SelectedItemBinding="{Binding Type}" 
        DisplayMemberPath="Name"
        >
    

    (另外,去掉Mode=TwoWay——这是该属性绑定的默认设置,无论如何你都会得到它)。

    【讨论】:

    • 谢谢!第一种方法有效 - 但这种方式我得到了 Id 和参考,我认为这不是一个吸引人的解决方案。我尝试了第二个,但它对我不起作用......没有选定的项目。
    • @johannesp 哦,哎呀——绑定选定的项目和选定的值应该没问题,而且你都可以得到,但你需要确保 ToolTypeId 在每个 Type 上匹配 Type 在填充之前网格。对于第二个版本,您是否尝试取消注释 Equals() 覆盖?
    • 仍然无法正常工作:/ SelectedItemBinding="{Binding ToolType}" SelectedValueBinding="{Binding ToolType}" 是我作为属性插入的。我假设您对 ToolType 的意思是“ToolTypeModel”字段,我将其称为 Type。无论哪种方式,都行不通。
    • 好的,我明白了!我必须添加SelectedItemBinding="{Binding Type}" SelectedValueBinding="{Binding Id}" SelectedValuePath="Id" - 现在可以了!谢谢!!
    • 哇——谢谢!我永远不会抓住这个错误!我实现了您在编辑中所做的方式 - 并发现它只有在实现 Equals 时才有效。
    猜你喜欢
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    • 2017-11-11
    • 2010-12-26
    • 2017-01-16
    • 1970-01-01
    相关资源
    最近更新 更多