【问题标题】:I don't understand how to integrate my Model in my Viewmodel我不明白如何将我的模型集成到我的视图模型中
【发布时间】:2019-09-05 13:49:13
【问题描述】:

我正在使用 Wpf、CaliburnMicro 和 mvvm 模式构建一个小型个人项目。 该应用程序是一个触摸屏,可让用户查看室温并让他选择他想要的 Climatizer 上的订单(通风、冷、热、关闭),并将显示该订单是否已从 climatizer 中“确认”。(反馈令)。来自 Climatizer 的数据来自串行通信。 我有一个 ClimControlModel 类,它封装了 RoomTemperature、Order 和 FeedBack Order 等数据。

我已经简化了 ClimControl 类,因此代码在 StackOverflow 上不会占用太多行,我只是想在视图中显示 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}");
        }
    }
}

ShellViewModel:

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,因为对象本身没有改变,改变的是对象属性的值。 但是,在这种情况下,“最佳实践”是什么,就好像我在 ViewModel 中创建了 RoomTemperature、Order、Feedback Order 属性一样,我怎样才能在 ViewModel 中自动更改它们的值?

【问题讨论】:

    标签: c# mvvm caliburn.micro


    【解决方案1】:

    随着模型的属性发生变化,视图注意到变化的唯一方法是模型实现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 事件。

    【讨论】:

    • 它有效,谢谢!很抱歉,我没有足够的分数来支持您的回答。
    猜你喜欢
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多