wpf - 实例化新视图模型时如何添加新视图
问题描述
WPF 新手,不确定如何以编程方式实例化包装新图表及其数据集合的新视图模型。目前,它包括以下内容,但不确定设置它的最佳方式。
class ChartViewModel
{
public ChartViewModel()
{
CartesianChart chart = new CartesianChart();
chart.Series = new SeriesCollection
{
new GLineSeries
{
Title = "Pressure",
Values = new GearedValues<double>(),
},
new GLineSeries
{
Title = "Pulse",
Values = new GearedValues<int>(),
}
};
}
}
然后,我需要将新图表添加到视图中。CartesianChart 对象是 UIElement,当我只在没有此类的主窗口中对其进行测试时,它的工作方式如下。
stackPanel.Children.Add(chart);
但是该类似乎无法访问 xaml,并且我无法添加实际的视图模型类,因为那不是 UIElement,只有图表是。基本上每次上一个图表填满这样的东西时都需要创建一个新的图表实例:
ChartViewModel tempChart = new ChartViewModel();
chartRepo.Add(tempChart); //chart repo is a list of ChartViewModels
所以它需要自己的 SeriesCollection 和 UIElement。感谢您的任何建议。
解决方案
如果您想动态添加新图表,您必须使用DataTemplate
模板来制作图表数据。
由DataTemplate
图表组成的 绑定到ChartDataModel
. 我们可以使用 aListView
来显示图表(数据模板)。视图模型ChartViewModel
用作ListView.ItemsSource
并持有一组ChartData
.
每个ChartData
映射到一个新图表。
每当您ChartDataModel
在 中创建新图表ChartViewModel
并将其添加到ChartModels
时,ListView
都会自动创建新图表。
风景:
<ListView ItemsSource="{Binding ChartModels}">
<ListView.DataContext>
<ChartViewModel />
</ListView.DataContext>
<ListView.ItemTemplate>
<DataTemplate DataType="ChartDataModel">
<CartesianChart>
<CartesianChart.Series>
<LineSeries Title="Pressure" Values="{Binding PressureValues}" />
<LineSeries Title="Pulse" Values="{Binding PulseValues}" />
</CartesianChart.Series>
</CartesianChart>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
该模型:
class ChartDataModel
{
public ChartDataModel()
{
this.PressureValues = new ChartValues<double>();
this.PulseValues = new ChartValues<double>();
}
public ChartValues<double> PressureValues { get; set; }
public ChartValues<double> PulseValues { get; set; }
}
视图模型:
class ChartViewModel : INotifyPropertyChanged
{
public ChartViewModel()
{
this.ChartModels = new ObservableCollection<ChartDataModel>();
CreateNewChart();
}
private void CreateNewChart()
{
var newChartDataModel = new ChartDataModel()
{
PressureDataValues = new ChartValues<double>()
{
10, 20, 30, 40, 50
},
PulseDataValues = new ChartValues<double>()
{
100, 200, 300, 400, 500
}
};
this.ChartModels.Add(newChartDataModel);
}
private ObservableCollection<ChartDataModel> chartModels;
public ObservableCollection<ChartDataModel> ChartModels
{
get => this.chartModels;
set
{
if (Equals(value, this.chartModels)) return;
this.chartModels = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
推荐阅读
- dictionary - 将 NLTK 树转换为字典数组
- node.js - Set Bearer Token to get authorization on Google Cloud Storage objects
- java - onActivityResult wont work after onBackPressed
- javascript - AngularJS - display a default option at the top of a dynamic select dropdown list?
- javascript - Exporting Mongoose methods in Node.js (TypeError: Cannot read property 'name' of null)
- azure - 安装在本地计算机上的 Azure VM 代理是否将数据发布到 Azure/与 azure 相关的任何服务/任何其他 URL?
- cordova - Ionic Cordova 平台添加 ios 失败,未加载库:/usr/local/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)
- excel - 无法更改字体颜色
- wcf - 添加的服务引用的自动生成代码中的循环基类依赖错误
- c++ - 如何设置永久背景颜色?