PropertyBinding.cs 5.2 KB
Newer Older
潘栩锋's avatar
潘栩锋 committed
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 123 124 125 126 127 128 129 130 131 132 133 134
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections;

namespace Misc
{
    public class BindingOperations
    {
        
        // 摘要:
        //     描述绑定中数据流的方向。
        public enum BindingMode
        {
            // 摘要:
            //     导致对源属性或目标属性的更改可自动更新对方。此绑定类型适用于可编辑窗体或其他完全交互式 UI 方案。
            TwoWay = 0,
            //
            // 摘要:
            //     当绑定源(源)更改时,更新绑定目标(目标)属性。如果要绑定的控件为隐式只读控件,则适用此绑定类型。例如,可以绑定到如股市代号之类的源。或者,可能目标属性没有用于进行更改(例如表的数据绑定背景色)的控件接口。如果不需要监视目标属性的更改,则使用
            //     System.Windows.Data.BindingMode.OneWay 绑定模式可避免 System.Windows.Data.BindingMode.TwoWay
            //     绑定模式的系统开销。
            OneWay = 1
        }
        /// <summary>
        /// 当绑定源(源)更改时,更新绑定目标(目标)属性
        /// </summary>
        /// <param name="src"></param>
        /// <param name="srcPropertyName"></param>
        /// <param name="target"></param>
        /// <param name="targetPropertyName"></param>
        public static void SetBinding(INotifyPropertyChanged src, string srcPropertyName, INotifyPropertyChanged target, string targetPropertyName) 
        {
            SetBinding(src, srcPropertyName, target, targetPropertyName, BindingMode.OneWay);
        }
        public static void SetBinding(INotifyPropertyChanged src, string srcPropertyName, IList target, int index) 
        {

            Type type_s = src.GetType();
            Type type_t = target.GetType();
            System.Reflection.PropertyInfo pi_s = type_s.GetProperty(srcPropertyName);
            if (pi_s == null)
                return;
            
            object obj = pi_s.GetValue(src,null);
            target[index] = obj;

            src.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == srcPropertyName)
                {
                    object o = pi_s.GetValue(src, null);
                    target[index] = obj;
                }
            };
                    
        }
        public static void SetBinding(INotifyPropertyChanged src, string srcPropertyName, Action func) 
        {
            func();
            src.PropertyChanged += (s, e) =>
            {
                if (srcPropertyName==e.PropertyName)
                {
                    func();
                }
            };
        }
        public static void SetBinding(INotifyPropertyChanged src, string[] srcPropertyNames, Action func) 
        {
            func();
            src.PropertyChanged += (s, e) =>
            {
                if (srcPropertyNames.Contains(e.PropertyName)) 
                {
                    func();
                }
            };
        }
        public static void SetBinding(INotifyPropertyChanged src, string srcPropertyName, INotifyPropertyChanged target, string targetPropertyName, BindingMode mode) 
        {
            Type type_s = src.GetType();
            Type type_t = target.GetType();
            System.Reflection.PropertyInfo pi_s = type_s.GetProperty(srcPropertyName);
            System.Reflection.PropertyInfo pi_t = type_t.GetProperty(targetPropertyName);
            if (pi_s == null || pi_t == null)
                return;
      
            switch (mode) 
            {
                case BindingMode.OneWay://src->target
                    {
                        object obj = pi_s.GetValue(src,null);
                        pi_t.SetValue(target, obj, null);

                        src.PropertyChanged += (s, e) =>
                        {
                            if (e.PropertyName == srcPropertyName)
                            {
                                object o = pi_s.GetValue(src, null);
                                pi_t.SetValue(target, o, null);
                            }
                        };
                    }break;
                case BindingMode.TwoWay://src->target then target->src
                    {
                        object obj = pi_s.GetValue(src,null);
                        pi_t.SetValue(target, obj, null);

                        src.PropertyChanged += (s, e) =>
                        {
                            if (e.PropertyName == srcPropertyName)
                            {
                                object o = pi_s.GetValue(s, null);
                                pi_t.SetValue(target, o, null);
                            }
                        };

                        target.PropertyChanged += (s, e) =>
                        {
                            if (e.PropertyName == targetPropertyName)
                            {
                                object o = pi_t.GetValue(s, null);
                                pi_s.SetValue(src, o, null);
                            }
                        };
                    }break;
            }
        }
    }

}