简单的计数案例,ViewModel开启辅助线程,模拟后端运行,该方式可以扩展为项目中的后端线程数采及运算呈现,便于实时监控数据的场景。
代码如下:
MyCommand
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace MVVMCountDemo.ViewModel
{
public class MyCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public MyCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
}
}
Notify
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace MVVMCountDemo.ViewModel
{
public abstract class Notify : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
Window.xaml
<Window x:Class="MVVMCountDemo.MainWindow"
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:MVVMCountDemo"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label FontSize="30" Content="{Binding Seconds}" Foreground="Black" HorizontalAlignment="Left" Margin="141,85,0,0" VerticalAlignment="Top" Height="110" Width="230"/>
<Button Content="开始/清零" HorizontalAlignment="Left" Margin="203,224,0,0" VerticalAlignment="Top" Width="100" Command="{Binding StartOrResetCommand}"/>
</Grid>
</Window>
MainWindow.cs
using MVVMCountDemo.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace MVVMCountDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new CountDemoViewModel();
}
}
}
CountDemoViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Threading;
namespace MVVMCountDemo.ViewModel
{
public class CountDemoViewModel:Notify
{
private DispatcherTimer timer;
private int seconds = 0;
public int Seconds
{
get { return seconds; }
set
{
if (seconds != value)
{
seconds = value;
OnPropertyChanged(nameof(Seconds));
}
}
}
public ICommand StartOrResetCommand { get; private set; }
public CountDemoViewModel()
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += Timer_Tick;
StartOrResetCommand = new MyCommand(StartOrReset);
}
int currentCount = 0;
int lastCount = 0;
private void Timer_Tick(object sender, EventArgs e)
{
currentCount++;
Seconds = currentCount - lastCount;
}
private void StartOrReset()
{
if (timer.IsEnabled)
{
timer.Stop();
Seconds = 0;
lastCount = currentCount;
}
else
{
timer.Start();
}
}
}
}