我不明白如何将我的模型集成到我的视图模型中
I don't understand how to integrate my Model in my Viewmodel
我正在使用 Wpf、CaliburnMicro 和 mvvm 模式构建一个小型个人项目。
该应用程序是一个触摸屏,让用户可以看到室温并让他 select 他想要的气候器订单(通风、冷、热、关),并且会显示该订单是否 "confirmed" 来自气候调节器。(反馈订单)。来自 Climatizer 的数据来自串行通信。
我有一个 ClimControlModel class,它封装了 RoomTemperature、Order 和 FeedBack Order 等数据。
我已经简化了 ClimControl class 所以 Whosebug 上的代码不会占用太多行,我只是想在视图中显示 RoomTemperature。
ClimControlModel.cs:
namespace WpfMetroCaliburn.Models
{
public enum OrderValue
{
OFF,
VENT1,
VENT2,
VENT3,
COLD,
HOT,
OFFLINE
}
public class ClimControlModel
{
public float RoomTemperature { get; set; } = 99F; // fake value for testing
public OrderValue Order { get; set; }
public OrderValue FeedbackOrder { get; set; }
public ClimControlModel()
{
// will change val of RoomTemperature and FeedcackOrder every 5 seconds
ChangePropretiesPeriodically();
}
// this will simulate updating datas from Serial
public void ChangePropretiesPeriodically()
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnPropretiesChangeTimerEvent);
aTimer.Interval = 5000;
aTimer.Enabled = true;
}
// Assigning random values to RoomTemperature and Feedback Order for testing purposes
private void OnPropretiesChangeTimerEvent(object sender, ElapsedEventArgs e)
{
Array values = Enum.GetValues(typeof(OrderValue));
Random random = new Random();
FeedbackOrder = (OrderValue)values.GetValue(random.Next(values.Length));
Random rnd = new Random();
RoomTemperature = rnd.Next(20, 33);
Console.WriteLine($"FakeClimControlModel: RoomTemperature is now: {RoomTemperature}");
}
}
}
外壳视图模型:
namespace WpfMetroCaliburn.ViewModels
{
public class ShellViewModel : Screen
{
private ClimControlModel _clim;
public ClimControlModel Clim
{
get { return _clim; }
set {
_clim = value;
NotifyOfPropertyChange(() => Clim);
}
}
public ShellViewModel()
{
Clim = new ClimControlModel();
}
}
}
Xaml:
Window x:Class="WpfMetroCaliburn.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfMetroCaliburn.Views"
mc:Ignorable="d"
Title="ShellView" Height="450" Width="800">
<Grid>
<TextBlock x:Name="Clim_RoomTemperature" FontSize="25"></TextBlock>
</Grid>
</Window>
我知道它不起作用,因为 ClimControlModel 的实例实际上不会触发 NotifyOfPropertyChange,因为对象本身不会改变,改变的是对象属性的值。
然而,在那种情况下 "best practice" 会是什么,就像我在 ViewModel 中创建 RoomTemperature、Order、Feedback Order 属性一样,我如何才能在 ViewModel 中自动更改它们的值?
随着模型的属性发生变化,视图注意到变化的唯一方法是模型实现 INotifyPropertyChanged
并在 属性 变化时引发 NotifyPropertyChanged
.
换句话说,对于模型中的每个属性,更改此样式:
public float RoomTemperature { get; set; }
至
private float roomTemperature;
public float RoomTemperature
{
get => this.roomTemperature;
set
{
this.roomTemperature=value;
this.NotifyPropertyChanged();
}
}
如果您在 ViewModel 中添加了类似的属性,则模型更改时不会通知他们。
另一种方法是让 ViewModel 订阅 Timer 事件,然后引发 NotifyPropertyChanged
个事件。
我正在使用 Wpf、CaliburnMicro 和 mvvm 模式构建一个小型个人项目。 该应用程序是一个触摸屏,让用户可以看到室温并让他 select 他想要的气候器订单(通风、冷、热、关),并且会显示该订单是否 "confirmed" 来自气候调节器。(反馈订单)。来自 Climatizer 的数据来自串行通信。 我有一个 ClimControlModel class,它封装了 RoomTemperature、Order 和 FeedBack Order 等数据。
我已经简化了 ClimControl class 所以 Whosebug 上的代码不会占用太多行,我只是想在视图中显示 RoomTemperature。
ClimControlModel.cs:
namespace WpfMetroCaliburn.Models
{
public enum OrderValue
{
OFF,
VENT1,
VENT2,
VENT3,
COLD,
HOT,
OFFLINE
}
public class ClimControlModel
{
public float RoomTemperature { get; set; } = 99F; // fake value for testing
public OrderValue Order { get; set; }
public OrderValue FeedbackOrder { get; set; }
public ClimControlModel()
{
// will change val of RoomTemperature and FeedcackOrder every 5 seconds
ChangePropretiesPeriodically();
}
// this will simulate updating datas from Serial
public void ChangePropretiesPeriodically()
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnPropretiesChangeTimerEvent);
aTimer.Interval = 5000;
aTimer.Enabled = true;
}
// Assigning random values to RoomTemperature and Feedback Order for testing purposes
private void OnPropretiesChangeTimerEvent(object sender, ElapsedEventArgs e)
{
Array values = Enum.GetValues(typeof(OrderValue));
Random random = new Random();
FeedbackOrder = (OrderValue)values.GetValue(random.Next(values.Length));
Random rnd = new Random();
RoomTemperature = rnd.Next(20, 33);
Console.WriteLine($"FakeClimControlModel: RoomTemperature is now: {RoomTemperature}");
}
}
}
外壳视图模型:
namespace WpfMetroCaliburn.ViewModels
{
public class ShellViewModel : Screen
{
private ClimControlModel _clim;
public ClimControlModel Clim
{
get { return _clim; }
set {
_clim = value;
NotifyOfPropertyChange(() => Clim);
}
}
public ShellViewModel()
{
Clim = new ClimControlModel();
}
}
}
Xaml:
Window x:Class="WpfMetroCaliburn.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfMetroCaliburn.Views"
mc:Ignorable="d"
Title="ShellView" Height="450" Width="800">
<Grid>
<TextBlock x:Name="Clim_RoomTemperature" FontSize="25"></TextBlock>
</Grid>
</Window>
我知道它不起作用,因为 ClimControlModel 的实例实际上不会触发 NotifyOfPropertyChange,因为对象本身不会改变,改变的是对象属性的值。 然而,在那种情况下 "best practice" 会是什么,就像我在 ViewModel 中创建 RoomTemperature、Order、Feedback Order 属性一样,我如何才能在 ViewModel 中自动更改它们的值?
随着模型的属性发生变化,视图注意到变化的唯一方法是模型实现 INotifyPropertyChanged
并在 属性 变化时引发 NotifyPropertyChanged
.
换句话说,对于模型中的每个属性,更改此样式:
public float RoomTemperature { get; set; }
至
private float roomTemperature;
public float RoomTemperature
{
get => this.roomTemperature;
set
{
this.roomTemperature=value;
this.NotifyPropertyChanged();
}
}
如果您在 ViewModel 中添加了类似的属性,则模型更改时不会通知他们。
另一种方法是让 ViewModel 订阅 Timer 事件,然后引发 NotifyPropertyChanged
个事件。