Wpf 如何在实例化新视图模型时添加新视图
WPF新手,不知道如何以编程方式实例化包装新图表及其数据集合的新viewmodel。现在,它包括以下内容,但不确定设置它的最佳方式Wpf 如何在实例化新视图模型时添加新视图,wpf,livecharts,Wpf,Livecharts,WPF新手,不知道如何以编程方式实例化包装新图表及其数据集合的新viewmodel。现在,它包括以下内容,但不确定设置它的最佳方式 class ChartViewModel { public ChartViewModel() { CartesianChart chart = new CartesianChart(); chart.Series = new SeriesCollection
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>(),
}
};
}
}
但是这个类似乎无法访问xaml,我也无法添加实际的视图模型类,因为它不是UIElement,只有图表是。基本上,每次前一个图表充满以下内容时,都需要创建一个新的图表实例:
ChartViewModel tempChart = new ChartViewModel();
chartRepo.Add(tempChart); //chart repo is a list of ChartViewModels
所以它需要自己的seriecollection和ui元素。感谢您的推荐。视图模型正在实例化一个图表,它是一个UI元素。ViewModels应该只公开带有公共getter(有时是setter)的简单属性。视图应该读取这些属性并相应地更改其UI元素。ViewModel通常不包含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; }
}
公共类ChartViewModel
{
公共字符串FirstSeriestTLE{get;set;}
公共IEnumerable FirstSeriesValues{get;set;}
}
我建议您阅读一些关于MVVM模式的文章,以便更好地掌握它
编辑::由于您需要数量可变的图表,您可能应该添加ItemsControl,并将其ItemsSource绑定到chartviewmodels的ObservableCollection。设置itemscontrol的itemTemplate属性以设置每个项目的外观!(也就是说,图表和其他ui元素)如果要动态添加新图表,必须使用
DataTemplate
为图表数据设置模板
由图表组成的DataTemplate
绑定到ChartDataModel
。我们可以使用列表视图
来显示图表(数据模板)。视图模型ChartViewModel
用作ListView.ItemsSource
并保存一组ChartData
每个
ChartData
映射到一个新图表
每当您在ChartViewModel
中创建新的ChartDataModel
并将其添加到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; }
}
类ChartDataModel
{
公共图表数据模型()
{
this.PressureValues=新图表值();
this.PulseValues=新图表值();
}
公共图表值压力评估值{get;set;}
公共图表值脉冲值{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));
}
}
class ChartViewModel:INotifyPropertyChanged
{
公共图表视图模型()
{
this.ChartModels=新的ObservableCollection();
CreateNewChart();
}
私有void CreateNewChart()
{
var newChartDataModel=新ChartDataModel()
{
PressureDataValues=新图表值()
{
10, 20, 30, 40, 50
},
Pulstavalues=新图表值()
{
100, 200, 300, 400, 500
}
};
this.ChartModels.Add(newChartDataModel);
}
私有可观测收集模型;
公共可观测收集图表模型
{
get=>this.chartModels;
设置
{
if(等于(value,this.chartModels))返回;
这个.chartModels=值;
OnPropertyChanged();
}
}
公共事件属性更改事件处理程序属性更改;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
this.PropertyChanged?.Invoke(this,newpropertychangedeventargs(propertyName));
}
}
他需要在该视图模型上实现INotifyPropertyChanged。问题是我有未定义数量的图表需要创建并添加到堆栈面板。它将基于日志记录运行时间。所以我不能只在xaml?Ed中为所有图表加上标记,除非他要更新这些值,但是的,通常应该在基类上实现!在我看来,这个问题很像他打算更新这些价值观。我们收到了很多“为什么它不更新?”的问题;这不是一个无谓的担忧。
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));
}
}