WPF MVVW应用 模拟交通灯系统

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);
            }
        }

    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值