首页 > 解决方案 > 在 AvaloniaUI/ReactiveUI 应用程序的 DataGrid 中绑定 ComboBox DataTemplate

问题描述

我正在使用 AvaloniaUI/ReactiveUI 和 EF Core 构建一个 MVVM 应用程序,以便能够编辑一些包含数据的表。我想我使用 AvaloniaUI 的事实并没有起到太大的作用。如果我使用 WPF,问题可能是相同的(似乎更多是 ReactiveUI 问题)。

例如,假设有两个表,Classes 和 Instructors,其中 Classes 持有 Instructors 表的外键。

班级和讲师具有以下模型:

class Class
{
    //Primary key
    public int ID { get; set; }
    public string Name { get; set; }
    //Foreign key to Instructors table
    public int InstructorID { get; set; }
    //Navigation property
    public Instructor Instructor { get; set; }
}

class Instructor
{
    //Primary key
    public int ID { get; set; }
    public string Name { get; set; }
}

主视图模型包含这两个集合

public List<Class> Classes { get; set; }
public List<Instructor> Instructors { get; set; }

我希望这些类显示在 DataGrid 中。为此,我使用了这样的编程(类型安全)ReactiveUI 绑定

<DataGrid Name="DGClasses">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Name"
                        Binding="{Binding Name}" />
    <DataGridTextColumn Header="Instructor"
                        Binding="{Binding Instructor.Name}"/>
  </DataGrid.Columns>
</DataGrid>


...
this.OneWayBind(ViewModel, x => x.Classes, x => x.DGClasses.Items); 
this.Bind(ViewModel, x => x.SelectedClass, x => x.DGClasses.SelectedItem);
...

到目前为止,这很好用,尽管 Classes 表只包含 Instructors 表的外键(这通过 Class 类中的导航属性起作用),但 Instructor 列甚至显示了教师的姓名。

为了编辑一个类的 Instructor,该列应该使用 ComboBox 作为编辑器,这样我就可以从所有现有的 Instructor 中进行选择。我从

<DataGridTemplateColumn Header="Instructor">
  <DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
      <ComboBox Items="{Binding ??? }">
      </ComboBox>
    </DataTemplate>
  </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

但这就是我卡住的地方。直接绑定表达式不起作用,因为 Instructors 集合不是 Class 的子属性,并且我知道无法以编程方式将 Items 属性(WPF 中的 ItemsSource)绑定到 DataGrid 列的 DataTemplate 中。由于我对所有(顶级)元素使用编程 ReactiveUI 绑定,因此我也没有设置包含 DataGrid 的窗口的 DataContext 属性。

知道如何做到这一点吗?

标签: wpfreactiveuiavaloniaui

解决方案


您可以将您的组合框项目集合绑定到DataGrid(或仅使用Tag)上的一些特殊附加属性,并执行类似{Binding $parent[DataGrid].Tag}.


推荐阅读