不知道如何以编程方式实例化包装新图表及其数据收集的新视图模型。现在,它由以下内容组成,但不确定设置它的最佳方法。
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。谢谢你的建议。
发布于 2019-07-25 20:41:18
如果您想动态添加新图表,则必须使用DataTemplate
来模板图表数据。
由图表组成的DataTemplate
被绑定到ChartDataModel
。我们可以使用ListView
来显示图表(数据模板)。视图模型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));
}
}
发布于 2019-07-25 17:27:54
ViewModel正在实例化图表,这是一个UI元素。ViewModels只应该使用公共getter(有时还包括setter)公开简单的属性。视图应该读取这些属性并相应地更改其UI元素。ViewModels通常不包含UI元素。
也就是说,您应该在xaml (或xaml.cs)中实例化图表,然后将其属性绑定到ViewModel。链接视图和ViewModel,视图的DataContext属性必须是ViewModel实例。
ViewModel可以直接访问数据源(例如数据库),并将该数据源转换为随时供UI元素使用的值。
例如,您的视图可能包含如下内容:
<livechart:CartesianChart>
<livechart:CartesianChart.Series>
<Series Title="{Binding FirstSeriesTitle}" Values="{Binding FirstSeriesValues}"/>
</livechart:CartesianChart.Series>
</livechart:CartesianChart>
而你的ViewModel
public class ChartViewModel
{
public string FirstSeriesTitle { get; set; }
public IEnumerable<ChartPoint> FirstSeriesValues { get; set; }
}
我建议您阅读一些关于MVVM模式的文章,以便更好地掌握它!
因为需要可变数量的图表,所以可能应该添加一个ItemsControl,并将其ItemsSource绑定到chartviewmodels的ObservableCollection上。设置itemscontrol的itemTemplate属性以设置每个项的外观!(也就是说,图表和其他ui元素)
https://stackoverflow.com/questions/57207060
复制相似问题