zoukankan      html  css  js  c++  java
  • [开源]FreeSCADA的通道数据与控件属性关联以及自动刷新机制研究

    【参考文章】:

    1. WPF之Binding深入探讨, 地址:http://www.cnblogs.com/cappuccino/p/3251631.html

    1. 几个重要的类列表:

    a) Designer工程下的CommonBindingDialog.cs:

    b) Designer工程下的NumericBindingPanel.cs(或者StringBindingPanel.cs):

    c) CommonGUI工程下的SchemaDocument.cs(LoadSchema()和SaveSchema())和RunTime工程下的ShemaView.cs(LoadDocument())

    分别实现WPF界面的XMAL文件方式存储和XMAL文件方式载入,和实现WinForm下的WPF界面的载入

    2. 通道数据与控件属性关联(以及自动刷新机制):

    a) 通道数据与控件属性绑定:

    CommonBindingDialog.cs中的事件响应方法(Create association按钮被按下):

    private void CreateAssociationButton_Click(object sender, EventArgs e)
    {
        SavePanelStateAndClose();
    
        if (propertyList.SelectedIndex >= 0 && bindingTypes.SelectedIndex >= 0)
        {
            BaseBindingPanelFactory factory = (BaseBindingPanelFactory)bindingTypes.SelectedItem; // factory在这里执行过后,就是NumericBindingPanel.cs里定义的NumericBindingPanelFactory类型了
            bindingPanel = factory.CreateInstance(); // bindingPanel的具体类型是NumericBindingPanel还是StringBindingPanel,在这里得到了重新定义(不再是基类的BaseBindingPanel类型了)
            bindingPanel.Initialize(element, propertyList.SelectedItem as PropertyWrapper, null);
            bindingPanel.Parent = panel1;
            bindingPanel.Dock = DockStyle.Fill;
            CreateAssociationButton.Enabled = false;
            bindingTypes.Enabled = false;
        }
    }

    CommonBindingDialog.cs中的事件响应方法(Save按钮被按下):

    private void saveButton_Click(object sender, EventArgs e)
    {
        SavePanelStateAndClose();
        if (activeBindings.Count > 0)
        {
            foreach (PropertyWrapper key in activeBindings.Keys)
            {
                DependencyObject depObj;
                DependencyProperty depProp;
                System.Windows.Data.BindingBase binding = activeBindings[key];
    
                if (key.GetWpfObjects(out depObj, out depProp) && binding != null)
                    BindingOperations.SetBinding(depObj, depProp, binding);
            }
        }
        DialogResult = DialogResult.OK;
        Close();
    }

    继续来看SavePanelStateAndClose方法的实现:

    private void SavePanelStateAndClose()
    {
        if (bindingPanel != null)
        {
            BindingBase binding = bindingPanel.Save(); // 见NumericBindingPanel类的Save()定义
            if (binding != null)
                activeBindings[bindingPanel.Property] = binding; // activeBindings为Dictionary<PropertyWrapper, BindingBase>,bindingPanel.Property为PropertyWrapper
    
            bindingPanel.Dispose();
            bindingPanel = null;
        }
    }

    我们再继续深入NumericBindingPanel.cs里面定义的Save方法:

    public override System.Windows.Data.BindingBase Save()
    {
        if (channel != null)
        {
            System.Windows.Data.Binding bind = new System.Windows.Data.Binding("Value");
            ChannelDataProvider cdp = new ChannelDataProvider();
            cdp.ChannelName = channel.PluginId + "." + channel.Name;
            bind.Source = cdp; // 绑定的源数据为通道数据
            bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            cdp.Refresh();
    
            ComposingConverter conv = new ComposingConverter();
            if (checkBox1.Checked)
            {
                RangeConverter rc = new RangeConverter();
                rc.Min = Decimal.ToDouble(minEdit.Value);
                rc.Max = Decimal.ToDouble(maxEdit.Value);
                conv.Converters.Add(rc);
            }
    
            conv.Converters.Add(new Kent.Boogaart.Converters.TypeConverter(cdp.Channel.Type, Property.PropertyType));
            bind.Converter = conv;
    
            bind.Mode = BindingMode.TwoWay;
    
            DependencyObject depObj;
            DependencyProperty depProp;
            if (Property.GetWpfObjects(out depObj, out depProp))
                bind.FallbackValue = depObj.GetValue(depProp);
    
            return bind;
        }
        else 
            return base.Save();
    }

     这里关键是WPF编程方式下System.Windows.Data.Binding类的使用,下面我们来看一个简单的WPF示例工程,该工程演示了WPF中一个TextBox的Text属性与

    数据源的绑定、以及子线程中绑定数据源值更新的自动同步:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    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;
    
    using System.Threading;
    using System.ComponentModel;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public class DataSource : INotifyPropertyChanged
            {
                private int _index;
    
                public int Index
                {
                    get { return _index; }
                    set
                    {
                        _index = value;
                        if (PropertyChanged != null)
                        {
                            this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Index"));
                        }
                    }
                }
                public event PropertyChangedEventHandler PropertyChanged;
            } 
    
            System.Windows.Data.Binding _bind;
            Thread _thread;
            DataSource _dataSource;
            bool _run;
    
            public MainWindow()
            {
                InitializeComponent();
                
                _dataSource = new DataSource();
                // System.Windows.Data.Binding方式
                _bind = new System.Windows.Data.Binding();
                _bind.Source = _dataSource;
                _bind.Path = new PropertyPath("Index");
                _bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                this.textBox1.SetBinding(TextBox.TextProperty, _bind);
    
                _run = true;
                _thread = new Thread(Test);
                _thread.Start();
            }
    
            void Test()
            {
                while (_run) // 里面不能放阻塞式的方法,否则逻辑可能一直卡住
                {
                    _dataSource.Index++;
                    Thread.Sleep(100);
                }
            }
    
            private void Window_Closing(object sender, CancelEventArgs e)
            {
                _run = false;
                if (_thread != null)
                {
                    _thread.Join();
                    _thread = null;
                }
            }
    
        }
    }

    工程界面:

    实际运行界面:

  • 相关阅读:
    IntelliJ IDEA 14.03 java 中文文本处理中的编码格式设置
    应聘感悟
    STL string分析
    CUDA SDK VolumeRender 分析 (1)
    BSP
    CUDA SDK VolumeRender 分析 (3)
    CUDA SDK VolumeRender 分析 (2)
    Windows软件发布时遇到的一些问题
    Ten Commandments of Egoless Programming (转载)
    复习下光照知识
  • 原文地址:https://www.cnblogs.com/jayhust/p/5837542.html
Copyright © 2011-2022 走看看