浏览代码

修改plc读取和写入bug

user_lt 1 年之前
父节点
当前提交
14d97d8624

+ 58 - 0
BlankApp1/BlankApp1/Controls/AsyncObservableCollection.cs

@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace PLCTool.Controls
+{
+    public class AsyncObservableCollection<T> : ObservableCollection<T>
+    {
+        //获取当前线程的SynchronizationContext对象
+        private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;
+        public AsyncObservableCollection() { }
+        public AsyncObservableCollection(IEnumerable<T> list) : base(list) { }
+        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
+        {
+
+            if (SynchronizationContext.Current == _synchronizationContext)
+            {
+                //如果操作发生在同一个线程中,不需要进行跨线程执行         
+                RaiseCollectionChanged(e);
+            }
+            else
+            {
+                //如果不是发生在同一个线程中
+                //准确说来,这里是在一个非UI线程中,需要进行UI的更新所进行的操作         
+                _synchronizationContext.Post(RaiseCollectionChanged, e);
+            }
+        }
+        private void RaiseCollectionChanged(object param)
+        {
+            // 执行         
+            base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
+        }
+        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
+        {
+            if (SynchronizationContext.Current == _synchronizationContext)
+            {
+                // Execute the PropertyChanged event on the current thread             
+                RaisePropertyChanged(e);
+            }
+            else
+            {
+                // Post the PropertyChanged event on the creator thread             
+                _synchronizationContext.Post(RaisePropertyChanged, e);
+            }
+        }
+        private void RaisePropertyChanged(object param)
+        {
+            // We are in the creator thread, call the base implementation directly         
+            base.OnPropertyChanged((PropertyChangedEventArgs)param);
+        }
+    }
+}

+ 61 - 43
BlankApp1/BlankApp1/ViewModels/MonitorManageViewModel/PLCReadViewModel.cs

@@ -3,6 +3,8 @@ using BizService;
 using Model.Dto;
 using Model.Entities;
 using PLCTool.Common;
+using PLCTool.Controls;
+using Prism.Commands;
 using Prism.Mvvm;
 using System;
 using System.CodeDom;
@@ -27,9 +29,17 @@ namespace PLCTool.ViewModels.MonitorManageViewModel
           
             _iBasPlcItemConfigService = iBasPlcItemConfigService;
             _mapper = mapper;
-            GetPLCConfig();
+            OnLoadCommand = new DelegateCommand(OnLoad);
+     
             ReadPLCRealValue();
         }
+
+        private void OnLoad()
+        {
+            GetPLCConfig();
+        }
+
+
         #region 私有方法
         /// <summary>
         /// 获取PLC配置
@@ -40,61 +50,69 @@ namespace PLCTool.ViewModels.MonitorManageViewModel
             plcConfigs = _mapper.Map<List<bas_plc_item_config>, List<BasPlcItemConfigDto>>(plclist);
             foreach (var plc in plcConfigs)
             {
-                PLCItemList.Add(plc);
+                var find = PLCItemList.FirstOrDefault(X => X.PlcAddress == plc.PlcAddress);
+                if(find == null) 
+                {
+                    PLCItemList.Add(plc);
+                }
+                
             }
         }
-
-        #endregion
-        #region 命令绑定
-        private ObservableCollection<BasPlcItemConfigDto> plcItemList=new ObservableCollection<BasPlcItemConfigDto>();
-        public ObservableCollection<BasPlcItemConfigDto> PLCItemList
-        {
-            get { return plcItemList; }
-            set { plcItemList = value; RaisePropertyChanged(); }
-        }
         private void ReadPLCRealValue()
         {
-                Task.Run(async () =>
+            Task.Run(async () =>
+            {
+                while (true)
                 {
-                    while(true)
+                    //更新界面上的值
+                    Application.Current.Dispatcher.Invoke(() =>
                     {
-                        //更新界面上的值
-                        Application.Current.Dispatcher.Invoke(() =>
+                        foreach (var item in PLCItemList)
                         {
-                            foreach (var item in PLCItemList)
+                            //没有连接 plc,直接退出
+                            if (!PLCCom.GetInstance().IsConnectPLC())
                             {
-                                //没有连接 plc,直接退出
-                                if(!PLCCom.GetInstance().IsConnectPLC())
-                                {
+                                break;
+                            }
+                            string plcAddr = item.PlcAddress;
+                            string plcAddType = item.PlcAddType;
+                            switch (plcAddType)
+                            {
+                                case "bool":
+                                    item.RealValue = PLCCom.GetInstance().ReadPlcObject(plcAddr, VarType.Bit);
+                                    break;
+                                case "word":
+                                    item.RealValue = PLCCom.GetInstance().ReadPlcObject(plcAddr, VarType.Word);
+                                    break;
+                                case "dword":
+                                    item.RealValue = PLCCom.GetInstance().ReadPlcObject(plcAddr, VarType.DWord);
+                                    break;
+                                case "real":
+                                    item.RealValue = PLCCom.GetInstance().ReadPlcObject(plcAddr, VarType.Real);
                                     break;
-                                }
-                                string plcAddr = item.PlcAddress;
-                                string plcAddType = item.PlcAddType;
-                                switch (plcAddType)
-                                {
-                                    case "bool":
-                                        item.RealValue = PLCCom.GetInstance().ReadPlcObject(plcAddr, VarType.Bit);
-                                        break;
-                                    case "word":
-                                        item.RealValue = PLCCom.GetInstance().ReadPlcObject(plcAddr, VarType.Word);
-                                        break;
-                                    case "dword":
-                                        item.RealValue = PLCCom.GetInstance().ReadPlcObject(plcAddr, VarType.DWord);
-                                        break;
-                                    case "real":
-                                        item.RealValue = PLCCom.GetInstance().ReadPlcObject(plcAddr, VarType.Real);
-                                        break;
-                                }
-
                             }
-                        });
 
-                        await Task.Delay(5000);
-                    }
+                        }
+                    });
 
-                });
+                    await Task.Delay(5000);
+                }
+
+            });
+        }
+        #endregion
+        #region 数据绑定
+        private AsyncObservableCollection<BasPlcItemConfigDto> plcItemList=new AsyncObservableCollection<BasPlcItemConfigDto>();
+        public AsyncObservableCollection<BasPlcItemConfigDto> PLCItemList
+        {
+            get { return plcItemList; }
+            set { plcItemList = value; RaisePropertyChanged(); }
         }
+
+        #endregion
+        #region 命令绑定
+        public DelegateCommand OnLoadCommand { set; get; }
         #endregion
-  
+
     }
 }

+ 15 - 6
BlankApp1/BlankApp1/ViewModels/MonitorManageViewModel/PLCWriteViewModel.cs

@@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
 using Model.Dto;
 using Model.Entities;
 using PLCTool.Common;
+using PLCTool.Controls;
 using Prism.Commands;
 using Prism.Mvvm;
 using System;
@@ -29,12 +30,16 @@ namespace PLCTool.ViewModels.MonitorManageViewModel
             _mapper = mapper;
             _logger= logger;
             WriteCommand = new DelegateCommand<object>(WriteToPlc);
+            OnLoadCommand = new DelegateCommand(OnLoad);
             GetPLCConfig();
         }
 
 
         #region 私有方法
-
+        private void OnLoad()
+        {
+            GetPLCConfig();
+        }
         private void WriteToPlc(object obj)
         {//没有连接 plc,直接退出
             if (!PLCCom.GetInstance().IsConnectPLC())
@@ -104,25 +109,29 @@ namespace PLCTool.ViewModels.MonitorManageViewModel
             plcConfigs = _mapper.Map<List<bas_plc_item_config>, List<BasPlcItemConfigDto>>(plclist);
             foreach (var plc in plcConfigs)
             {
-                PLCItemList.Add(plc);
+                var find = PLCItemList.FirstOrDefault(X => X.PlcAddress == plc.PlcAddress);
+                if (find == null)
+                {
+                    PLCItemList.Add(plc);
+                }
             }
         }
 
     
         #endregion
         #region 数据绑定
-        private ObservableCollection<BasPlcItemConfigDto> plcItemList = new ObservableCollection<BasPlcItemConfigDto>();
-        public ObservableCollection<BasPlcItemConfigDto> PLCItemList
+        private AsyncObservableCollection<BasPlcItemConfigDto> plcItemList = new AsyncObservableCollection<BasPlcItemConfigDto>();
+        public AsyncObservableCollection<BasPlcItemConfigDto> PLCItemList
         {
             get { return plcItemList; }
             set { plcItemList = value; RaisePropertyChanged(); }
         }
 
-    
+
         #endregion
 
         #region 命令绑定
-
+        public DelegateCommand OnLoadCommand { set; get; }
         public DelegateCommand<object> WriteCommand { set; get; }
         #endregion
     }

+ 6 - 0
BlankApp1/BlankApp1/Views/MonitorManageView/PLCReadView.xaml

@@ -4,9 +4,15 @@
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:PLCTool.Views.MonitorManageView"
+             xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
              mc:Ignorable="d" 
              d:DesignHeight="450" d:DesignWidth="800">
     <Grid>
+        <b:Interaction.Triggers>
+            <b:EventTrigger EventName="Loaded">
+                <b:InvokeCommandAction Command="{Binding OnLoadCommand}"/>
+            </b:EventTrigger>
+        </b:Interaction.Triggers>
         <DataGrid   ColumnWidth="*" AutoGenerateColumns="False" HeadersVisibility="All" CanUserAddRows="False"  SelectionUnit="FullRow" SelectionMode="Single"   RowHeaderWidth="0"
         ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}"  RowHeaderStyle="{StaticResource RowHeaderStyle}" RowStyle="{StaticResource DataGridRowtyle}"  AlternationCount="2"
        ItemsSource="{Binding PLCItemList}" IsReadOnly="True"  Padding="0">

+ 6 - 1
BlankApp1/BlankApp1/Views/MonitorManageView/PLCWriteView.xaml

@@ -3,11 +3,16 @@
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+              xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
              xmlns:local="clr-namespace:PLCTool.Views.MonitorManageView"
              mc:Ignorable="d" 
              d:DesignHeight="450" d:DesignWidth="800">
     <Grid>
-
+        <b:Interaction.Triggers>
+            <b:EventTrigger EventName="Loaded">
+                <b:InvokeCommandAction Command="{Binding OnLoadCommand}"/>
+            </b:EventTrigger>
+        </b:Interaction.Triggers>
         <DataGrid   ColumnWidth="*" AutoGenerateColumns="False" HeadersVisibility="All" CanUserAddRows="False"  SelectionUnit="FullRow" SelectionMode="Single"   RowHeaderWidth="0"
    ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}"  RowHeaderStyle="{StaticResource RowHeaderStyle}" RowStyle="{StaticResource DataGridRowtyle}"  AlternationCount="2"
   ItemsSource="{Binding PLCItemList}" IsReadOnly="True"  HorizontalScrollBarVisibility="Hidden" Padding="0" >