【发布时间】:2021-05-29 15:25:39
【问题描述】:
我正在尝试了解如何将ObservableCollection<*Dictionary<string, DBRecord>> 绑定到DataGrid 的ItemSource 属性。
您可以在下面看到在内存中代表我的数据库表的类。我需要这样做,因为表架构是在独立的 .xml 文件中描述的(我无法更改)。
public abstract class DBField {
public string Name;
public DBField(string name) {
Name = name;
}
}
public class DBValueField<T> : DBField {
public T Value;
public DBValueField(string name, T value) : base(name) {
Value = value;
}
}
public class DBTextField : DBValueField<string> {
public DBTextField(string name, string value) : base(name, value) { }
}
public class DBIntField : DBValueField<int> {
public DBIntField(string name, int value) : base(name, value)
{}
}
public class DBFloatField : DBValueField<float> {
public DBFloatField(string name, float value) : base(name, value)
{}
}
public class DBDoubleField : DBValueField<double> {
public DBDoubleField(string name, double value) : base(name, value)
{}
}
public class DBBoolField : DBValueField<bool> {
public DBBoolField(string name, bool value) : base(name, value)
{}
}
public class DBRecord {
public Dictionary<string, DBField> Fields { get; set; }
}
public class DBTable {
private readonly XmlSchema schema;
public List<DBRecord> Records { get; set; }
}
这是我的数据库视图模型:
public class DatabaseViewModel : BaseViewModel {
public Dictionary<string, DBTable> Tables { get; private set; }
public DBTable ActiveTable { get; private set; }
public ObservableCollection<DBRecord> ActiveData { get; set; }
}
我有一个 ComboBox,其中包含所有加载的数据库表的完整列表,并且我在该 ComboBox 下方有一个 DataGrid 元素。这个想法是,当您选择特定表时,ViewModel 将使用列(从表架构中检索)和值(值分配给 ActiveData 作为参考并从选定的组合框中的表)。 问题是我不明白如何正确地将这样的结构绑定到 DataGrid。
我的想法是:
- 知道如何访问数据的转换器
- 将数据映射到每个表的定制类(我真的想避免这种情况,因为不知道需要哪些表)
- 以某种方式将字典集合绑定到 DataGrid(尝试这样做但不太明白如何做)
- 以某种方式从代码隐藏中手动在 DataGrid 中插入行?
这是我的 WPF 标记:
<ComboBox x:Name="tablesComboBox"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="8"
Style="{StaticResource DarkFlatComboBox}"
ItemsSource="{Binding Tables, Mode=OneWay}"
DisplayMemberPath="Key"
SelectedValuePath="Value"
SelectionChanged="ComboBox_SelectionChanged"/>
<DataGrid x:Name="dataGrid"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="8"
AutoGenerateColumns="True"
LoadingRow="DataGrid_LoadingRow"
Style="{StaticResource DarkDataGrid}"
ItemsSource="{Binding ActiveTable.Records,
Mode=TwoWay}"/>
【问题讨论】:
-
不要这样做。展平/解构字典,使其成为一个简单的数据项列表。字典不是一个合理的数据源。这是一个特殊的集合,可提供非常快速的查找。大多数情况下,在 UI 中使用它会导致代码不自然且过于复杂(就像您的情况一样)。
-
@BionicCode Gotcha,试图做到这一点
-
@BionicCode 我设法用列表替换了字典。所以现在我绑定
List<DBRecord>转换为List<List<DBField>>。 DBField 有两个属性:Name 和 Value,其中 Name 是列名,Value 是该列的实际行值。如何正确设置 ItemsSource 的路径? -
不确定我是否正确理解您以及 DataGrid 应该如何呈现列表列表。通常您使用数据项列表作为数据源,其中每个项目显示为一行,该项目的每个属性构成一列。使用自动生成的表格,每个属性 name 都使列标题和属性值显示为单元格值。您可以手动定义列以自定义列名和/或属性映射和单元格布局。所以你想要的是
List<DBField>。 -
或者从您的数据模型/数据库结果创建一个
DataTable。您可以将其直接分配/绑定到DataGrid.ItemsSource。
标签: c# wpf mvvm binding datagrid