開源純C#工控網關+組態軟件(六)圖元組件


一、   圖元概述

圖元是構成人機界面的基本單元。如一個個的電機、設備、數據顯示、儀表盤,都是圖元。構建人機界面的過程就是鋪排、挪移、定位圖元的過程。

圖元設計是繪圖和編碼的結合。因為圖元不僅有顯示和動畫,還有背后操縱動畫的控制邏輯。

一個好的圖元設計框架,應該最大限度提高設計的效率和專業程度。

因為你找到一個會做美工的碼農,和會寫代碼的美工,都很困難,但是單獨找碼農和繪圖員卻一抓一大把。所以專業性意味着用人的靈活性,和省錢。而你招來一個美工,一個碼農,合作完成一個圖元組件,必須考慮減少兩人的交互,最好埋頭各干各的。並行作業,才有最高效率。

可以通過以下手段提高界面開發效率:

  • 前后端分離

前后端分離的設計模式有很多優點。前后端對設計者的要求是不同的。。

前端設計者需要考慮的是界面更直觀、美觀、清晰、大氣,可以熟練使用繪圖工具(例如Blend),可以不會編程。

后端設計者要考慮的是業務邏輯,如何有條不紊、准確執行。可以不會畫圖,但一般必然熟練編碼,使用設計工具(如Visual Studio)。

前后端分離便於設計者術業有專攻,前后端分工協作,互不干擾,並行工作,提高效率。

  • 專業的前端設計工具

對於繪圖員或美工,一個簡單易用、同時又有強大功能的趁手設計器是必須的。

繪圖板、動畫、整合、調色板,美工的全套裝備必須齊全;網格定位、縮放、旋轉、保存、撤銷,常規的設計器功能必須應有盡有。

  • 盡可能少的編碼

很多行業都有龐大的圖元庫。各種設備、開關、構件,各種非標組件,不斷會有新的圖元入庫。

因此,力求用最少的代碼實現盡可能多的功能,最大限度提升開發效率。一個強大的基類和一個方便的繼承是必要的。

二、   前后端分離的設計模式

  • 通過WPF實現前后端分離

看看百度百科對WPF的介紹:WPF(Windows Presentation Foundation)是微軟推出的基於Windows 的用戶界面框架,屬於.NET Framework 3.0的一部分。

它提供了統一的編程模型、語言和框架,真正做到了分離界面設計人員與開發人員的工作;同時它提供了全新的多媒體交互用戶圖形界面。

WPF通過一種MVVM(Model-View-ViewMode)的設計模式實現界面與編碼解耦。界面元素的顏色、動畫、形狀,可以方便的與代碼類的屬性綁定(Binding)。

綁定的便利在於,后台類的某屬性變化,馬上會自動反映到界面的變化,無需編寫代碼;界面元素的變化,也馬上會觸發屬性值的改變,這種方式天然適合人機界面的前后端分離設計。

同時,WPF提供XAML文件,是一種聲明式編程方式,類似於Android的界面文件、HTML,界面設計者與代碼編寫者只需要通過XAML文件交互,進一步達成前后端分離並行作業的目的。

  •  前后端交互的內容

繪圖員的工作:

使用Blend繪圖,使用故事板(Storyboard)制作動畫,定義動畫的視圖狀態(VisualState),綁定屬性如:

Text="{Binding BinName, RelativeSource={RelativeSource TemplatedParent}}"

碼農的工作:

定義一個CustomControl。繼承HMIControlBase

定義依賴項屬性如Running:

            public static readonly DependencyProperty RunningProperty = DependencyProperty.Register("Running", typeof(bool), typeof(Elevator),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender,
            new PropertyChangedCallback(OnValueChanged)));

屬性變化事件切換視圖狀態如

VisualStateManager.GoToState(this, _funcRun () ? "Run" : "Stop", true);

就這么簡單。

三、   繪圖與動畫

  • 強大的設計工具:Blend

Blend是VS2010起微軟提供的專業設計工具。早期曾經有三賤客(Blend,Design, Encoder ),后兩者已經合並入Blend。

在 Expression Blend 中,可以在美工板上繪制形狀、路徑和控件,然后修改其外觀和行為,從而直觀地設計界面元素。可以導入圖像、視頻和聲音,還可以導入和更改三維對象。

可以創建Storyboard實現幀動畫,定義狀態(VisualState),並設計觸發器(Trigger)觸發動畫。還可以定義樣式(Style)。

Blend對美工人員是簡單易上手的。按我的經驗,對於習慣AutoCAD工具的繪圖工程師,熟練掌握Blend一般在兩周內,就可以繪制復雜的動畫圖形。

所有的圖元組件均為CustomControl類型,這樣編輯好的圖元文件會自動加入到Generic.xaml文件。相應的圖元模板可在Blend內重新編輯。

 

  • 用代碼實現動畫

如果不用Blend,也可以用代碼直接實現動畫。部分對性能要求高、使用頻繁的圖元組件如Guage,LinkLine,可以繼承Control的OnRender方法並使用StreamGeometry這類的底層API繪圖,以達到最佳的性能。

StreamGeometry的優點是調用底層繪圖API,不生成多余的對象,而Blend在生成圖形過程中有大量冗余元素和對象,復雜的層次結構,在對性能要求較高的場合略顯笨重。

四、   強大的圖元基類

為了盡可能減少編碼,需要在圖元基類(HMIControlBase) 中實現盡可能多的功能;但又不能包辦一切,犧牲圖元自身的“個性”。要實現簡潔、強大、可擴展。

因此,我在圖元基類實現了所有界面元素共有的幾個基本功能:

  • 連線。

為了實現方便的連線,需要能自行設置圖元的錨點,作為拖放連線的連接點。

 

繼承GetLinkPositions方法,錨點分上下左右四個,每個錨點用一個Point確定相對位置。如果只有一個錨點,就返回單一的LinkPosition如下:

  public override LinkPosition[] GetLinkPositions()
        {
            return new LinkPosition[1]
                { 
                    new  LinkPosition(new Point(0.75,0),ConnectOrientation.Top),
                };
        }
  • 綁定變量表達式。

只要繼承基類,就可以彈出變量組態界面。

 

可以自行定義左邊的屬性樹。即繼承GetActions方法。注意這個樹狀結構支持嵌套,如某設備帶兩個電機(Motor),則電機的屬性列表會作為樹的子節點顯示。

public override string[] GetActions()
        {
            return new string[] { TagActions.VISIBLE, TagActions.CAPTION, TagActions.RUN, TagActions.ALARM, TagActions.DEVICENAME };
        }
  • 動畫顯示。

繼承SetTagReader方法,只要相關Tag變化,就會觸發動畫腳本。如

public override Action SetTagReader(string key, Delegate tagChanged)
        {
            switch (key)
            {
                case TagActions.RUN:
                    var _funcInRun = tagChanged as Func<bool>;
                    if (_funcInRun != null)
                    {
                        return delegate { VisualStateManager.GoToState(this, _funcInRun() ? "Running" : "NotRunning", true); };
                    }
                    else return null;
            }
            return base.SetTagReader(key, tagChanged);
        }

VisualStateManager.GoToState方法根據不同的狀態字,觸發了在Blend里定義的故事板動畫。

五、   如何實現:增加新圖元

圖元設計流程:

 

六、   下面的計划

寫一系列帖子,把架構、原理講清楚。大致如下:

  • 網關層接口概述
  • 上下位機通訊原理
  • 如何實現一個設備驅動
  • 如何設計圖元
  • VS插件模塊及原理
  • 歸檔模塊及文件格式
  • 如何進行功能擴展
  • 組態變量表達式實現

github地址:https://github.com/GavinYellow/SharpSCADA。QQ群:102486275


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM