MVVM我正确地实现了这一点

时间:2011-04-10 22:08:43

标签: c# wpf mvvm

我一直试图在上周或更长时间内围绕着mvvm,并且还在苦苦挣扎。我观看了Jason Dolingers MVVM视频,并通过了Reed Copsey的课程,仍然发现自己想知道我是否正确行事......我创建了一个非常简单的时钟应用程序,我将在下面发布。该程序的输出是预期的,但是如果我实际上正确使用该模式,我会更感兴趣。任何想法评论等将不胜感激。

我的模特

using System;
using System.Threading;

namespace Clock
{
    public class ClockModel
    {
        private const int TIMER_INTERVAL = 50;

        private DateTime _time;

        public event Action<DateTime> TimeArrived;

        public ClockModel()
        {
            Thread thread = new Thread(new ThreadStart(GenerateTimes));
            thread.IsBackground = true;
            thread.Priority = ThreadPriority.Normal;
            thread.Start();
        }

        public DateTime DateTime
        {
            get
            {
                return _time;
            }
            set
            {
                this._time = value;
                if (TimeArrived != null)
                {
                    TimeArrived(DateTime);
                }
            }
        }

        private void GenerateTimes()
        {
            while (true)
            {
                DateTime = DateTime.Now;
                Thread.Sleep(TIMER_INTERVAL);
            }
        }
    }
}

我的观点

<Window x:Class="Clock.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ViewModels="clr-namespace:Clock"
        Title="MainWindow" Height="75" Width="375">
    <Window.DataContext>
        <ViewModels:ClockViewModel />
    </Window.DataContext>
    <StackPanel Background="Black">
            <TextBlock Text="{Binding Path=DateTime}" Foreground="White" Background="Black" FontSize="30" TextAlignment="Center" />
    </StackPanel>
</Window>

我的观点模型

using System;
using System.ComponentModel;

namespace Clock
{
    public class ClockViewModel : INotifyPropertyChanged
    {
        private DateTime _time;
        private ClockModel clock;

        public ClockViewModel()
        {
            clock = new ClockModel();
            clock.TimeArrived += new Action<DateTime>(clock_TimeArrived);
        }

        private void clock_TimeArrived(DateTime time)
        {
            DateTime = time;
            this.RaisePropertyChanged("DateTime");
        }

        public DateTime DateTime 
        {
            get
            {
                return _time;
            }

            set
            {
                _time = value;
            }
        }


        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Raises the property changed event.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }
}

3 个答案:

答案 0 :(得分:2)

你这样做的方式很好。我只会改变一件事:将RaisePropertyChange的呼叫移动到属性的设置者。这通常是如何完成的,它会阻止您在设置属性时忘记引发通知。

答案 1 :(得分:1)

在我看来,虽然您可能有兴趣将Model方法委托给Command,但您可以将其附加到Loaded,但您的实施在关注点分离方面看起来很不错你的主UI的事件。这绝对是个人偏好,但作为良好做法,我倾向于尝试在ViewViewModelModel.Method之间保持1:1的关系:Command

答案 2 :(得分:0)

对于某些常规功能,当您开始触摸显示消息框时,使用MVVM非常容易。显示单独的窗口,以及视图和视图模型之间的通信。然后你会发现一些棘手的事情......