1、应用 net6 wpf MVVMToolkit 8.0 工程搭建
2、界面分离view,Model
3、自定义控件
using CommunityToolkit.Mvvm.Messaging;
using MVVMToolkit测试.Models;
using MVVMToolkit测试.ViewModels;
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.Shapes;
namespace MVVMToolkit测试.Views
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
Task t1,t2;
private bool runStatus;
private CancellationTokenSource cts1,cts2;
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
WeakReferenceMessenger.Default.Register<string>(this, OnReceive);
runStatus = false;
cts1 = new CancellationTokenSource();
cts2 = new CancellationTokenSource();
//生产随机数
WeakReferenceMessenger.Default.Register<string, string>(this, "Rand",ShowRandInfo);
}
private void ShowRandInfo(object recipient, string message)
{
Task.Run(() => {
this.Dispatcher.Invoke(() => {
textBlockRandNuber.Text = message;
});
});
}
private void OnReceive(object recipient, string message)
{
string c = borderStatus.Background.ToString();
if (c == Brushes.Red.ToString())
{
borderStatus.Background = new SolidColorBrush(Colors.Green);
}
else
{
borderStatus.Background = new SolidColorBrush(Colors.Red);
}
if (!runStatus)
{
runStatus = true;
t1 = new Task(() => TaskMetod(),cts1.Token);
t1.Start();
t2 = new Task(new Action(Fun()),cts2.Token);
t2.Start();
}
else
{
runStatus = false;
cts1.Cancel();
cts2.Cancel();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
#region task线程模拟交通灯
private Action Fun()
{
return new Action(() => {
Task.Run(() => {
this.Dispatcher.BeginInvoke(() => {
listBoxLog.Items.Add($"{DateTime.Now}:南北方向开始。。。");
if (listBoxLog.Items.Count > 20)
{
listBoxLog.Items.Clear();
}
RunLightGreen_A.Background = new SolidColorBrush(Colors.Red);
RunLightRed_A.Background = new SolidColorBrush(Colors.Gray);
RunLightYellow_A.Background = new SolidColorBrush(Colors.Gray);
});
});
while (runStatus)
{
#region 业务流程
Task.Run(() =>
{
this.Dispatcher.Invoke(() =>
{
listBoxLog.Items.Add($"{DateTime.Now}:测试开始");
if (listBoxLog.Items.Count > 20)
{
listBoxLog.Items.Clear();
}
});
});
//绿灯 3S
Task.Run(async () =>
{
this.Dispatcher.Invoke(new Action(() =>
{
RunLightGreen_A.Background = new SolidColorBrush(Colors.Green);
RunLightRed_A.Background = new SolidColorBrush(Colors.Gray);
RunLightYellow_A.Background = new SolidColorBrush(Colors.Gray);
}));
});
Thread.Sleep(3000);
//黄灯 闪2s
Task.Run(async () =>
{
this.Dispatcher.Invoke(new Action(() =>
{
RunLightGreen_A.Background = new SolidColorBrush(Colors.Gray);
RunLightRed_A.Background = new SolidColorBrush(Colors.Gray);
RunLightYellow_A.Background = new SolidColorBrush(Colors.Yellow);
RunLightYellow_A.State = State.EnableInit;
}));
});
Thread.Sleep(2000);
//红灯5S
Task.Run(async () =>
{
this.Dispatcher.Invoke(new Action(() =>
{
RunLightYellow_A.State = State.Init;
RunLightRed_A.Background = new SolidColorBrush(Colors.Red);
RunLightGreen_A.Background = new SolidColorBrush(Colors.Gray);
RunLightYellow_A.Background = new SolidColorBrush(Colors.Gray);
}));
});
Thread.Sleep(5000);
Task.Run(() =>
{
this.Dispatcher.Invoke(() =>
{
listBoxLog.Items.Add($"{DateTime.Now}:测试结束");
if (listBoxLog.Items.Count > 20)
{
listBoxLog.Items.Clear();
}
});
});
Thread.Sleep(1000);
}
#endregion
});
}
private void TaskMetod()
{
Task.Run(() => {
this.Dispatcher.BeginInvoke(() => {
listBoxLog.Items.Add($"{DateTime.Now}:东西方向开始。。。");
if (listBoxLog.Items.Count > 20)
{
listBoxLog.Items.Clear();
}
RunLightGreen.Background = new SolidColorBrush(Colors.Red);
RunLightRed.Background = new SolidColorBrush(Colors.Gray);
RunLightYellow.Background = new SolidColorBrush(Colors.Gray);
});
});
while (runStatus)
{
#region 业务流程
Task.Run(() => {
this.Dispatcher.Invoke(() => {
listBoxLog.Items.Add($"{DateTime.Now}:测试开始");
if (listBoxLog.Items.Count > 20)
{
listBoxLog.Items.Clear();
}
});
});
//红灯5S
Task.Run(() =>
{
this.Dispatcher.Invoke(new Action(() =>
{
string color = LightRed.Background.ToString();
if (color == Brushes.Red.ToString())
{
LightRed.Background = new SolidColorBrush(Colors.Green);
}
else
{
LightRed.Background = new SolidColorBrush(Colors.Red);
}
}
));
this.Dispatcher.Invoke(new Action(() =>
{
RunLightYellow.State = State.Init;
RunLightRed.Background = new SolidColorBrush(Colors.Red);
RunLightGreen.Background = new SolidColorBrush(Colors.Gray);
RunLightYellow.Background = new SolidColorBrush(Colors.Gray);
}));
});
Thread.Sleep(5000);
//绿灯3S
Task.Run(() =>
{
this.Dispatcher.Invoke(new Action(() =>
{
RunLightRed.Background = new SolidColorBrush(Colors.Gray);
RunLightYellow.Background = new SolidColorBrush(Colors.Gray);
RunLightGreen.Background = new SolidColorBrush(Colors.Green);
}));
});
Thread.Sleep(3000);
//黄灯闪2S
Task.Run(() =>
{
this.Dispatcher.Invoke(new Action(() =>
{
RunLightGreen.Background = new SolidColorBrush(Colors.Gray);
RunLightRed.Background = new SolidColorBrush(Colors.Gray);
RunLightYellow.Background = new SolidColorBrush(Colors.Yellow);
RunLightYellow.State = State.EnableInit;
}));
});
Thread.Sleep(2000);
Task.Run(() => {
this.Dispatcher.Invoke(() => {
listBoxLog.Items.Add($"{DateTime.Now}:测试结束");
if (listBoxLog.Items.Count > 20)
{
listBoxLog.Items.Clear();
}
});
});
Task.Run(() =>
{
this.Dispatcher.Invoke(new Action(() =>
{
RunLightYellow.State = State.Init;
}));
});
Thread.Sleep(1000);
#endregion
}
}
#endregion
}
}
<Window x:Class="MVVMToolkit测试.Views.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:MVVMToolkit测试.Views"
xmlns:localA="clr-namespace:MVVMToolkit测试"
mc:Ignorable="d"
Title="MainWindow" Height="804" Width="800">
<Grid>
<StackPanel >
<StackPanel Orientation="Horizontal">
<TextBlock Text=" a" Width="50"/>
<TextBox Width="200" Text="{Binding calculateModel.a}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text=" b" Width="50"/>
<TextBox Width="200" Text="{Binding calculateModel.b}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text=" c" Width="50"/>
<TextBox Width="200" Text="{Binding calculateModel.c}"/>
</StackPanel>
<Button Content="开始" Command="{Binding addCommand}" Height="30" Width="50" HorizontalAlignment="Left" Click="Button_Click" />
<Border x:Name="borderStatus" Background="Red" Height="30" Width="66" HorizontalAlignment="Left" >
</Border>
<ListBox x:Name="listBoxLog" Height="100" Background="Gray"/>
<StackPanel Orientation="Horizontal" Margin="10">
<localA:LightControl1 x:Name="RedLight" State="Warning" Width="50" Height="50" BorderThickness="5"/>
<localA:LightControl1 x:Name="lc1" State="Init" Width="20" Height="20" BorderThickness="2"/>
<localA:LightControl1 State="Running" Width="20" Height="20" BorderThickness="1"/>
<localA:LightControl1 State="EnableWarning" Width="50" Height="50" BorderThickness="5"/>
<localA:LightControl1 State="EnableInit" Width="20" Height="20" BorderThickness="2"/>
<localA:LightControl1 State="EnableRunning" Width="20" Height="20" BorderThickness="1"/>
</StackPanel>
<Grid Height="275" Width="792">
<StackPanel>
<Canvas>
<localA:LightControl1 x:Name="RunLightRed" State="Warning" Width="50" Height="50" BorderThickness="1" Canvas.Left="476" Canvas.Top="83" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<localA:LightControl1 x:Name="RunLightGreen" State="Running" Width="50" Height="50" BorderThickness="1" HorizontalAlignment="Center" Canvas.Top="193" VerticalAlignment="Top" RenderTransformOrigin="0.437,0.914" Canvas.Left="476"/>
<localA:LightControl1 x:Name="RunLightYellow" State="Init" Width="50" Height="50" BorderThickness="1" HorizontalAlignment="Center" Canvas.Top="138" VerticalAlignment="Top" Canvas.Left="476"/>
<localA:LightControl1 x:Name="RunLightRed_A" State="Warning" Width="50" Height="50" BorderThickness="1" Canvas.Left="272" Canvas.Top="10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<localA:LightControl1 x:Name="RunLightGreen_A" State="Running" Width="50" Height="50" BorderThickness="1" Canvas.Top="10" RenderTransformOrigin="0.437,0.914" Canvas.Left="382" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<localA:LightControl1 x:Name="RunLightYellow_A" State="Init" Width="50" Height="50" BorderThickness="1" Canvas.Top="10" Canvas.Left="327" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Border x:Name="LightRed" Background="Red" Width="50" Height="50" CornerRadius="5" HorizontalAlignment="Left" VerticalAlignment="Top" Canvas.Left="7" Canvas.Top="147"/>
</Canvas>
<Label Content="交通灯模拟" Width="577" FontSize="20" RenderTransformOrigin="0.5,0.5">
<Label.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleY="-0.077"/>
<RotateTransform/>
<TranslateTransform Y="0.332"/>
</TransformGroup>
</Label.RenderTransform>
</Label>
</StackPanel>
</Grid>
<StackPanel>
<Label Content="当前时间" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBox Width="200" Text="{Binding CurrentTime}" VerticalAlignment="Bottom"/>
</StackPanel>
<Canvas>
<Button x:Name="btn_StartThread" Command="{Binding BackThreadCommand}" Height="40" Width="100" Content="后台线程"></Button>
<TextBlock Text="0000" x:Name="textBlockRandNuber" Width="300" Height="40" HorizontalAlignment="Left" FontSize="20" TextAlignment="Center" Background="DarkRed" Canvas.Left="242" Canvas.Top="8"></TextBlock>
</Canvas>
</StackPanel>
</Grid>
</Window>
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 MVVMToolkit测试
{
public class LightControl1 : Control
{
public static readonly DependencyProperty StateProperty = DependencyProperty.Register(
"State", typeof(State), typeof(LightControl1), new PropertyMetadata(State.Init, OnStateChanged));
public State State
{
get { return (State)GetValue(StateProperty); }
set { SetValue(StateProperty, value); }
}
static LightControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(LightControl1), new FrameworkPropertyMetadata(typeof(LightControl1)));
}
public void UpdateBreathingLight()
{
if (State == State.EnableWarning || State == State.EnableRunning || State == State.EnableInit)
{
VisualStateManager.GoToState(this, "Enable", true);
}
else
{
VisualStateManager.GoToState(this, "UnEnable", true);
}
}
//OnApplyTemplate方法保证在控件的模板被应用到控件上后会被调用。
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
UpdateBreathingLight();
}
private static void OnStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
LightControl1 control = d as LightControl1;
control.UpdateBreathingLight();
}
}
public enum State
{
Warning,
Running,
Init,
EnableWarning,
EnableRunning,
EnableInit
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MVVMToolkit测试">
<Style TargetType="{x:Type local:LightControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:LightControl1}">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Border x:Name="stateLight"
Background="{TemplateBinding Background}"
BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5" />
<Border
Background="Transparent"
BorderBrush="Gray" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="StateEnable">
<VisualState x:Name="Enable">
<Storyboard>
<DoubleAnimation AutoReverse="True" RepeatBehavior="Forever" Storyboard.TargetName="stateLight"
Storyboard.TargetProperty="Opacity" From="0.1" To="1"
Duration="0:0:0.3" />
</Storyboard>
</VisualState>
<VisualState x:Name="UnEnable" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="State" Value="Init">
<Setter Property="Background" Value="Orange" />
</Trigger>
<Trigger Property="State" Value="Warning">
<Setter Property="Background" Value="Red" />
</Trigger>
<Trigger Property="State" Value="Running">
<Setter Property="Background" Value="Green" />
</Trigger>
<Trigger Property="State" Value="EnableInit">
<Setter Property="Background" Value="Orange" />
</Trigger>
<Trigger Property="State" Value="EnableWarning">
<Setter Property="Background" Value="Red" />
</Trigger>
<Trigger Property="State" Value="EnableRunning">
<Setter Property="Background" Value="Green" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
using MVVMToolkit测试.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
namespace MVVMToolkit测试.Models
{
public class MainViewModel : ObservableObject
{
public CalucateModel? calculateModel { get; set; }
private string currentTime;
public MainViewModel()
{
calculateModel = new CalucateModel();
calculateModel.a = 1;
calculateModel.b = 10;
calculateModel.c = calculateModel.a + calculateModel.b;
//第三步:给命令赋值一个方法,当命令被触发时会自动调用赋值的方法
addCommand = new RelayCommand(add);
BackThreadCommand = new RelayCommand(GetSourceNumber);
StartUpdateTimer();
}
//第一步:定义一个命令
public RelayCommand addCommand { get; set; }
//顶二步:定义一个普通的方法
public void add()
{
//calculateModel.a = 11;
//calculateModel.b = 11;
calculateModel.c = calculateModel.a + calculateModel.b;
WeakReferenceMessenger.Default.Send<string>(calculateModel.c.ToString());
}
public string CurrentTime
{
get => currentTime;
set => SetProperty(ref currentTime, value);
}
private void StartUpdateTimer()
{
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Interval = TimeSpan.FromSeconds(1);
dispatcherTimer.Tick += (a, b) => UpdateTime();
dispatcherTimer.Start();
}
private void UpdateTime()
{
CurrentTime = DateTime.Now.ToString("F");
}
public RelayCommand BackThreadCommand { get; set; }
public void GetSourceNumber()
{
string result = GetRandomString(10);
WeakReferenceMessenger.Default.Send<string, string>(result, "Rand");
}
int time;
public string GetRandomString(int num)
{
string randomString = "";
for (int i = 0; i < num; i++)
{
randomString += CreateRandomString();
}
return randomString.Substring(0,10);
}
public string CreateRandomString()
{
int number;
char ch1;
string randomStr = null;
//为了让每次的随机数不同
this.time++;
long num2 = DateTime.Now.Ticks + this.time;
Random random = new Random(((int)(((ulong)num2) & 0xffffffffL)) | ((int)(num2 >> this.time)));
int temp = random.Next();
//如果随机的长度为0,设为1
if (temp % 11 == 0)
{
temp = 1;
}
//长度为1-10位,根据随机数字的奇偶性来确定是字母还是数字
for (int j = 0; j < temp % 11; j++)
{
number = random.Next();
if (number % 2 == 0)
ch1 = (char)('0' + (char)(number % 10));
else
ch1 = (char)('A' + (char)(number % 26));
randomStr += ch1.ToString();
}
return randomStr;
}
}
}
using CommunityToolkit.Mvvm.ComponentModel;
namespace MVVMToolkit测试.ViewModels
{
public class CalucateModel : ObservableObject
{
//计算a+b=c
private int _a;
private int _b;
private int _c;
public int a
{
get { return _a; }
set
{
SetProperty(ref _a, value);
}
}
public int b
{
get { return _b; }
set
{
SetProperty(ref _b, value);
}
}
public int c
{
get { return _c; }
set
{
SetProperty(ref _c, value);
}
}
}
}