需要帮助将事件驱动代码分成尊重MVVM模式的层

时间:2013-04-18 19:17:03

标签: c# wpf mvvm

我有一个标题为NewCalibrationView.xaml / .cs的视图,它有一个ViewModel NewCalibrationViewModel.cs

视图的xaml:

<StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Left" >
    <Label Content="Run Time:" FontSize="16" FontWeight="Bold" Margin="10,0,0,0"/>
    <TextBlock Name="ClockTextBlock" Text="00:00:00:00" FontSize="16" Foreground="Red" Margin="5" FontWeight="Bold"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
    <Label Content="Sample Count:" FontSize="16" FontWeight="Bold" Margin="10,0,0,0"/>
    <TextBlock Text="0" Name="SampleCountDigit" Foreground="Red" FontSize="16" FontWeight="Bold" Margin="5"/>
</StackPanel>

正如我所看到的,我有一个显示各种停止表的TextBlock,目前运行秒表的代码位于视图后面的代码中(NewCalibrationView.cs)

public partial class NewCalibrationView: UserControl
{
    private DispatcherTimer dt = new DispatcherTimer();
    private Stopwatch stopWatch = new Stopwatch();

    private string _currentTime = string.Empty;
    private int _sampleCount = 0;

    public NewCalibrationView()
    {
        InitializeComponent();

        dt.Tick += new EventHandler(dt_Tick);
        dt.Interval = new TimeSpan(0, 0, 0, 0, 1);
    }

    private void dt_Tick(object sender, EventArgs e)
    {
        if (stopWatch.IsRunning)
        {
            TimeSpan ts = stopWatch.Elapsed;

            _currentTime = String.Format("{0:00}:{1:00}:{2:00}", ts.Hours, ts.Minutes, ts.Seconds);

            ClockTextBlock.Text = _currentTime;

            if (ts.Seconds%8 == 0)
            {
                _sampleCount++;
                SampleCountDigit.Text = _sampleCount.ToString();
            }
        }
    }

    private void StartButton_Click(object sender, RoutedEventArgs e)
    {
        ClockTextBlock.Foreground = Brushes.Green;
        stopWatch.Start();
        dt.Start();
    }

因为此代码直接在DispatchTimer的Tick事件的事件处理程序(dt.Tick();)中更新视图,所以我很难确定在代码隐藏中要留下什么以及在ViewModel中放置什么

鉴于我在此处展示的代码隐藏代码,View中的内容以及ViewModel应该包含哪些内容?

首先,我认为应该将StartButton_Click()转换为一个Command(我通常放在VM中),但如果是这样的话,那么仅仅这样就意味着我必须要声明DispatchTimer和StopWatch也进入VM,这意味着其余代码(事件处理程序,其注册等)必须在VM中。

这听起来不错吗?

2 个答案:

答案 0 :(得分:3)

如果是我,我会把它全部移到视图模型中。我将2 Text的{​​{1}}属性绑定到我的视图模型上的2个字符串。如上所述,将TextBlock命令属性绑定到viewmodel上的Button。此外,您可以在viewmodel上保留一个布尔属性,该属性绑定到ICommand的颜色(您需要数据触发器)

答案 1 :(得分:1)

我会考虑使用MVVM工具包。我个人使用并喜欢MVVM Light Toolkit,但还有其他类似的东西。

我喜欢MVVM Light Toolkit,它易于使用,简单,并附带出色的文档和样本。

使用MVVM建立后,将命令,文本元素绑定到ViewModel。然后,您可以在ViewModel中处理您的事件。只需将您的命令绑定为事件即可。

我希望有所帮助。如果您需要更多详细信息,请通知我,我可以回复。