C# WPF - DataGridComboBoxColumn ItemsSource

joh*_*tin 3 c# wpf xaml

我目前正在努力使用 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; }
}
Run Code Online (Sandbox Code Playgroud)

和类 ToolTypeModel

public class ToolTypeModel
{
    public long Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

数据存储到数据库中并加载到我的 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在 DataGrid 中显示数据并尝试添加 DataGridComboBoxColumn 以选择对应工具的 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>
Run Code Online (Sandbox Code Playgroud)

它显示了 ToolTypes 的所有元素,不显示我的 Tool 引用的所选元素。

我有什么想法可以在 ComboBoxColumn 中查找 ToolTypes 并将引用的 Type 显示为所选项目?

提前致谢。

15e*_*153 5

SelectedValuePath是将通过SelectedValueBinding. 因此,SelectedValueBinding必须绑定到相同类型的属性。

<DataGridComboBoxColumn 
    Header="Typ"
    SelectedValueBinding="{Binding Type, Mode=TwoWay}" 
    SelectedValuePath="Id"
    DisplayMemberPath="Name">
Run Code Online (Sandbox Code Playgroud)

如果你有一个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; }
}
Run Code Online (Sandbox Code Playgroud)

在 XAML 中:

<DataGridComboBoxColumn 
    Header="Typ"
    SelectedValueBinding="{Binding ToolTypeId}" 
    SelectedValuePath="Id"
    DisplayMemberPath="Name">
Run Code Online (Sandbox Code Playgroud)

但我不认为那是你想要的。我认为很明显您想ToolTypeModel在您的Type财产中获得一个实际实例。

所以这应该有效(我刚刚测试过)。但是,请注意:覆盖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();
    }
}
Run Code Online (Sandbox Code Playgroud)

XAML:

<DataGridComboBoxColumn
    Header="Type"
    SelectedItemBinding="{Binding Type}" 
    DisplayMemberPath="Name"
    >
Run Code Online (Sandbox Code Playgroud)

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