• 用wpf替代winform 解决PLC数据量过大页面卡顿的问题


    winform 由于不是数据驱动, 页面想刷新数据必须刷新控件, wpf则不用. 可以利用wpf 的数据绑定和IOC, 页面中的消息传递, itemscontrol 实现大量数据刷新, 上位机页面不卡顿

    跨页面传值, 可以用两种方法: Toolkit.Mvvm中的Message和IOC. 下面是代码:

    using Microsoft.Extensions.DependencyInjection;
    using NavTest.Eneities;
    using NavTest.Views;
    using System;
    using System.Collections.ObjectModel;
    using System.Data;
    using System.Linq;
    using System.Reflection;
    using System.Windows;
    
    namespace NavTest
    {
        /// 
        /// Interaction logic for App.xaml
        /// 
        public partial class App : Application
        {
            public App() => Services = ConfigureServices();
    
            public IServiceProvider? Services { get; }
    
            public new static App Current => (App)Application.Current;
    
            private IServiceProvider? ConfigureServices()
            {
                ServiceCollection services = new ServiceCollection();
    
                //View
                #region ViewModel,View 注入
    
                services.AddSingleton<NewMainView>();
                services.AddSingleton<Page1>();
                services.AddSingleton<Page2>();
                services.AddSingleton<Page3>();
                services.AddSingleton<Page5>();
                var viewModelTypes = Assembly.GetExecutingAssembly().GetTypes()
                    .Where(t => t.Name.EndsWith("ViewModel"));
    
                foreach (var type in viewModelTypes)
                {
                    services.AddScoped(type);
                }
    
                //services.AddSingleton(sp => new Page2()
                //{
                //    DataContext = sp.GetService()
                //});
    
    
                #endregion
    
                //PLC注入
    
                services.AddSingleton<PLCModels>();
    
    
                return services.BuildServiceProvider();
            }
    
            private void Application_Startup(object sender, StartupEventArgs e)
            {
                NewMainView newMainView = this.Services?.GetService<NewMainView>();
                newMainView.Show();
                //MainView? mainView = this.Services?.GetService();
                //mainView.DataContext = this.Services?.GetService();
                //mainView.Show();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    模型定义:

    using CommunityToolkit.Mvvm.ComponentModel;
    using System.ComponentModel;
    
    namespace NavTest.Eneities
    {
        public partial class PLCModel : INotifyPropertyChanged
        {
            public int Id { get; set; }
    
            public string? Name { get; set; }
    
            public string? DataType { get; set; }
    
            //[ObservableProperty]
            //private int plcValue;
    
            private int plcValue;
    
            public event PropertyChangedEventHandler? PropertyChanged;
    
            public int PlcValue
            {
                get => plcValue;
                set
                {
                    if (plcValue != value)
                    {
                        plcValue = value;
                        NotifyPropertyChanged(nameof(PlcValue));
                    }
    
                }
            }
    
            private void NotifyPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace NavTest.Eneities
    {
        public partial class PLCModels
        {
            public PLCModels()
            {
                for (int i = 0; i < 200; i++)
                {
                    pLCModels.Add(new PLCModel()
                    {
                        Id = i,
                        PlcValue = i,
                        Name = $"名字{i}",
                    });
                }
            }
    
            public ObservableCollection<PLCModel> pLCModels { get; set; } = new();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    主页面产生数据:

    using CommunityToolkit.Mvvm.ComponentModel;
    using CommunityToolkit.Mvvm.Input;
    using NavTest.Eneities;
    using NavTest.Views;
    using NPOI.SS.Formula.Functions;
    using System;
    using System.Collections.ObjectModel;
    using System.Threading.Tasks;
    using System.Windows;
    
    namespace NavTest.ViewModels
    {
        public partial class NewMainViewModel : ObservableRecipient
        {
    
            public NewMainViewModel(Page1 page1, Page2 page2, Page3 page3, Page5 page5, PLCModels pLCModelsIoc)
            {
                this.page1 = page1;
                this.page2 = page2;
                this.page3 = page3;
                this.page5 = page5;
                this.pLCModelsIoc = pLCModelsIoc;
                IsActive = true;
                this.MyContent = page2;
                PlcGetValue();
            }
    
            [ObservableProperty]
            private object? myContent;
            private readonly Page1 page1;
            private readonly Page2 page2;
            private readonly Page3 page3;
            private readonly Page5 page5;
            private  PLCModels pLCModelsIoc;
    
    
            [ObservableProperty]
            private ObservableCollection<PLCModel> pLCModels;
    
    
            private int myUshort1;
    
            public int MyUshort1
            {
                get => myUshort1;
                set => SetProperty(ref myUshort1, value, true);
            }
    
            [RelayCommand]
            public void MaxNormor(Window window)
            {
                window.WindowState =
                    window.WindowState == WindowState.Maximized
                        ? WindowState.Normal
                        : WindowState.Maximized;
            }
    
            [RelayCommand]
            public void SwitchPage(string str)
            {
    
                switch (str)
                {
                    case "main":
                        //this.MyContent;
                        break;
                    case "page1":
                        this.MyContent = page1;
                        break;
                    case "page2":
                        this.MyContent = page2;
                        break;
                    case "page3":
                        this.MyContent = page3;
                        break;
                    case "page5":
                        this.MyContent = page5;
                        break;
                    default:
                        break;
                }
            }
    
    
            private void PlcGetValue()
            {
                Task.Run(async () =>
                {
    
                    while (true)
                    {
                        await Task.Delay(500);
    
                        //用Message传递
                        PLCModels = new();
                        for (int i = 0; i < 90; i++)
                        {
                            var random = new Random();
                            PLCModels.Add(new()
                            {
                                Id = i,
                                Name = $"Name{i}",
                                PlcValue = random.Next(1, 500)
                            });
                            if (i == 10)
                            {
                                MyUshort1 = random.Next(1, 500);
                            }
                        }
    
                        //用Ioc传递
                        for (int j = 0; j < 200; j++)
                        {
                            var random = new Random();
                            pLCModelsIoc.pLCModels[j].PlcValue = random.Next(1, 500);
                        }
                    }
                });
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122

    用ViewModel的Message 传值:

    using CommunityToolkit.Mvvm.ComponentModel;
    using CommunityToolkit.Mvvm.Messaging;
    using CommunityToolkit.Mvvm.Messaging.Messages;
    using NavTest.Eneities;
    using System.Collections.ObjectModel;
    
    namespace NavTest.ViewModels
    {
        /// 
        /// 用ViewModel 的 Message传递变化的值
        /// 
        public partial class Page2ViewModel : ObservableRecipient, IRecipient<PropertyChangedMessage<int>>
        {
            [ObservableProperty]
            private ObservableCollection<PLCModel> pLCModels;
    
            public Page2ViewModel()
            {
                IsActive = true;
            }
    
            public void Receive(PropertyChangedMessage<int> message)
            {
                if (message.Sender is NewMainViewModel vm)
                {
                    this.PLCModels = vm.PLCModels;
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    <UserControl
        x:Class="NavTest.Views.Page2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:con="clr-namespace:ValueConverters;assembly=ValueConverters"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:hc="https://handyorg.github.io/handycontrol"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:local="clr-namespace:NavTest.Views"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mv="clr-namespace:NavTest.ViewModels"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:tt="clr-namespace:NavTest.Eneities"
        xmlns:vc="clr-namespace:NavTest.Components"
        d:DataContext="{d:DesignInstance mv:Page2ViewModel}"
        d:DesignHeight="450"
        d:DesignWidth="800"
        FontSize="22"
        mc:Ignorable="d">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="0.1*" />
                <RowDefinition />
            Grid.RowDefinitions>
    
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                <TextBlock Foreground="White" Text="用viewModel的消息传递" />
            StackPanel>
    
            <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
                <ItemsControl AlternationCount="2" ItemsSource="{Binding PLCModels}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel />
                        ItemsPanelTemplate>
                    ItemsControl.ItemsPanel>
    
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border x:Name="border" Padding="2" BorderThickness="2" BorderBrush="Cyan">
                                <StackPanel>
                                    <TextBlock Foreground="White" Text="{Binding Id}" />
                                    <TextBlock Foreground="White" Text="{Binding Name}" />
                                    <TextBlock Foreground="White" Text="{Binding PlcValue}" />
                                StackPanel>
                            Border>
                            <DataTemplate.Triggers>
                                <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                                    <Setter TargetName="border" Property="Background" Value="green" />
                                Trigger>
                            DataTemplate.Triggers>
                        DataTemplate>
                    ItemsControl.ItemTemplate>
                ItemsControl>
            ScrollViewer>
    
        Grid>
    
    UserControl>
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    用IOC传值:

    using CommunityToolkit.Mvvm.ComponentModel;
    using NavTest.Eneities;
    using System.Collections.ObjectModel;
    
    namespace NavTest.ViewModels
    {
        /// 
        /// 用Ioc传递变化的值
        /// 
        public partial class Page3ViewModel : ObservableObject
        {
    
    
            public Page3ViewModel(PLCModels pLCModelsIoc)
            {
                pLCModels = pLCModelsIoc.pLCModels;
            }
    
            [ObservableProperty]
            private ObservableCollection<PLCModel> pLCModels;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    <UserControl
        x:Class="NavTest.Views.Page3"
        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:hc="https://handyorg.github.io/handycontrol"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:local="clr-namespace:NavTest.Views"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mv="clr-namespace:NavTest.ViewModels"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:tt="clr-namespace:NavTest.Eneities"
        xmlns:vc="clr-namespace:NavTest.Components"
        d:DataContext="{d:DesignInstance mv:Page3ViewModel}"
        d:DesignHeight="450"
        d:DesignWidth="800"
        FontSize="24"
        mc:Ignorable="d">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="0.1*" />
                <RowDefinition />
            Grid.RowDefinitions>
    
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                <TextBlock Foreground="White" Text="用Ioc传递" />
            StackPanel>
    
            <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
                <ItemsControl AlternationCount="2" ItemsSource="{Binding PLCModels}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel />
                        ItemsPanelTemplate>
                    ItemsControl.ItemsPanel>
    
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border
                                x:Name="border"
                                Padding="2"
                                BorderBrush="Yellow"
                                BorderThickness="2">
                                <StackPanel>
                                    <TextBlock Foreground="White" Text="{Binding Id}" />
                                    <TextBlock Foreground="White" Text="{Binding Name}" />
                                    <TextBlock Foreground="White" Text="{Binding PlcValue}" />
                                StackPanel>
                            Border>
    
                            <DataTemplate.Triggers>
                                <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                                    <Setter TargetName="border" Property="Background" Value="Blue" />
                                Trigger>
                            DataTemplate.Triggers>
                        DataTemplate>
                    ItemsControl.ItemTemplate>
                ItemsControl>
            ScrollViewer>
        Grid>
    UserControl>
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    效果图:

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    LeetCode 0144. 二叉树的前序遍历:二叉树必会题
    javaScript中Math内置对象基本方法入门
    编程之美4 Nim游戏
    redisson之分布式锁实现原理(三)
    圣杯布局与双飞翼布局
    初识Java 7-1 多态
    Docker 容器
    MySQL面试题——MySQL常见查询
    不用任何比较运算符找出两个整数中的较大的值
    UE4 UEngine.GameInstance.WorldContext.World.Level.Actor.Component
  • 原文地址:https://blog.csdn.net/helldoger/article/details/133808192