c# - WPF 绑定到三层 ObservableCollection财产
问题描述
我有 3 个具有ObservableCollection<T>
彼此属性的级别子类。在MainViewModel
我创建ObservableCollection<Group>
的属性中,哪些Group
类的元素将位于TreeView
. 在每个Group
班级中,我都创建了子ObservableCollection<Parameter>
属性。最后在Parameter
我ObservableCollection<ParameterValue>
为存储值创建的课程中。注意:每个类都基于INotifyPropertyChanged
接口。让我们去代码。
Models.cs
:
//BaseModel implement INotifyPropertyChanged
public class ParameterValue: BaseModel
{
private DateTime dateTimeValue;
public DateTime DateTimeValue
{
get { return dateTimeValue; }
set
{
dateTimeValue = value;
NotifyPropertyChanged("DateTimeValue");
}
}
private double value;
public double Value
{
get { return value; }
set
{
this.value = value;
NotifyPropertyChanged("Value");
}
}
}
//BaseModel implement INotifyPropertyChanged
public class Parameter: BaseModel
{
public Parameter()
{
values = new ObservableCollection<ParameterValue>();
}
private ObservableCollection<ParameterValue> values;
public ObservableCollection<ParameterValue> Values
{
get { return values; }
set
{
values = value;
NotifyPropertyChanged("Values");
}
}
private int parameterId;
public int ParameterId
{
get { return parameterId; }
set
{
parameterId = value;
NotifyPropertyChanged("ParameterId");
}
}
private string parameterName;
public string ParameterName
{
get { return parameterName; }
set
{
parameterName = value;
NotifyPropertyChanged("ParameterName");
}
}
}
//BaseModel implement INotifyPropertyChanged
public class Group: BaseModel
{
public Group()
{
parameters = new ObservableCollection<Parameter>();
}
private ObservableCollection<Parameter> parameters;
public ObservableCollection<Parameter> Parameters
{
get { return parameters; }
set
{
parameters = value;
NotifyPropertyChanged("Parameters");
}
}
private int groupId;
public int GroupId
{
get { return groupId; }
set
{
groupId = value;
NotifyPropertyChanged("Id");
}
}
private string groupName;
public string GroupName
{
get { return groupName; }
set
{
groupName = value;
NotifyPropertyChanged("GroupName");
}
}
}
//Implementing INotifyPropertyChanged
public class BaseModel: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
ViewModels.cs
:
//BaseModel implement INotifyPropertyChanged
public class MainViewModel: BaseModel
{
public MainViewModel()
{
groups = new ObservableCollection<Group>();
//fill sample data instead of recieving from DB
for (int i = 1; i < 11; i++)
{
Group group = new Group { GroupId = i, GroupName = "Group " + i.ToString()};
groups.Add(group);
for (int j = 1; j < 11; j++)
{
Parameter param = new Parameter { ParameterId = j, ParameterName = "Parameter "+j.ToString()};
for (int k = 1; k < 51; k++)
{
ParameterValue val = new ParameterValue { DateTimeValue = DateTime.Now.AddSeconds(i*j-k), Value = (1000-k*5)/((i+j)+1)};
param.Values.Add(val);
}
group.Parameters.Add(param);
}
}
int l = 0;
}
private ObservableCollection<Group> groups;
public ObservableCollection<Group> Groups
{
get { return groups; }
set
{
groups = value;
NotifyPropertyChanged("Groups");
}
}
}
以及 View 角色中的 MainWindow.xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="75*" />
</Grid.ColumnDefinitions>
<TreeView x:Name="trv" Grid.Column="0" ItemsSource="{Binding Groups}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Parameters}">
<TextBlock Text="{Binding GroupName}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ParameterName}"></TextBlock>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<ListView Grid.Column="1" Background="Bisque" ItemsSource="{Binding Path=Groups.Parameters}">
<ListView.View>
<GridView>
<GridViewColumn Header="Date Time" DisplayMemberBinding="{Binding DateTimeValue}"/>
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
在MainViewModel
我简化了从 DB 接收的数据,用测试数据替换了嵌套的 for 循环。
- 我尝试以 MVVM 方式显示
TreeView
Parameter
数据中的选定内容。ListView
- 有
DataGroup
必要创建类SelectedItem
属性Parameter
以更准确地从数据库接收数据吗?当然是 MVVM 方式。
解决方案
在您的 ListView ItemSource 中,您必须像这样绑定到值...
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="75*" />
</Grid.ColumnDefinitions>
<TreeView x:Name="trv" Grid.Column="0" ItemsSource="{Binding Groups}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Parameters}">
<TextBlock Text="{Binding GroupName}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ParameterName}"></TextBlock>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<ListView Grid.Column="1"
Background="Bisque"
ItemsSource="{Binding SelectedItem.Values, ElementName=trv}">
<ListView.View>
<GridView>
<GridViewColumn Header="Date Time" DisplayMemberBinding="{Binding DateTimeValue}"/>
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
观察我如何绑定到 TreeView 的 SelectedItem。该选定项应为具有属性值的参数。
如果您选择 Group,则不会显示任何内容,因为 Group 没有 Values 集合。只有参数有。
推荐阅读
- python - 将行重复项转换为列/标题
- java - 扩展 WebSecurityConfigurerAdapter 不添加 CSP 标头
- discord - Discord.js 新的“/”命令
- fortran - 错误:缩减变量“v1”在外部上下文中是私有的
- swiftui - 变异运算符的左侧不可变:'product' 是一个 'let' 常量 SwiftUI
- typescript - 如何模拟 jest.mock 等 mocha 生态系统中的整个类/模块级依赖项?
- php - 如何在 ajax 中发送 http_response_code
- google-apps-script - 想要从我的谷歌表中更新 Adobe CS 下拉列表
- swift - 如何从 [(String?, [Contact])]() 获取联系人数组?
- java - 如果跳过 maven 测试,则跳过声纳插件执行