using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; namespace CPF { /// /// 简化绑定操作 /// public class BindingDescribe { internal BindingDescribe() { } public BindingDescribe(string sourceProperty) { PropertyName = sourceProperty; } public BindingDescribe(string sourceProperty, BindingMode binding) { PropertyName = sourceProperty; BindingMode = binding; } public BindingDescribe(object source, string sourceProperty, BindingMode binding) { PropertyName = sourceProperty; BindingMode = binding; Source = source; } public BindingDescribe(object source, string sourceProperty) { PropertyName = sourceProperty; Source = source; } public BindingDescribe(object source, string sourceProperty, Func convert) { PropertyName = sourceProperty; Source = source; Convert = convert; } public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func convert) { BindingMode = binding; PropertyName = sourceProperty; Source = source; Convert = convert; } public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func convert, Func convertBack) { BindingMode = binding; PropertyName = sourceProperty; Source = source; Convert = convert; ConvertBack = convertBack; } public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func convert, Func convertBack, Action SourceToTargetError, Action TargetToSourceError) { BindingMode = binding; PropertyName = sourceProperty; Source = source; Convert = convert; ConvertBack = convertBack; this.SourceToTargetError = SourceToTargetError; this.TargetToSourceError = TargetToSourceError; } public BindingDescribe(Action command) { Command = command; } /// /// 数据绑定的转换 /// public Func Convert { get; internal set; } public string PropertyName { get; internal set; } /// /// 简化绑定命令的命令,如果设置了该属性,则使用命令绑定 /// public Action Command { get; set; } //public CpfObject Owner { get; internal set; } /// /// 双向绑定,如果加数据转换器,两个转换器要对称,否则可能出现死循环或者其他错误 /// /// /// /// public static Binding operator ==(BindingDescribe property1, BindingDescribe property2) { var b = new Binding(property2.Source, property2.PropertyName, property1.PropertyName, BindingMode.TwoWay) { Convert = property2.Convert, ConvertBack = property1.Convert }; List list; var target = property1.Source as CpfObject; if (target == null) { throw new Exception("property1.Source必须是CpfObject"); } if (!target.Bindings.binds.TryGetValue(property1.PropertyName, out list)) { list = new List(); target.Bindings.binds.Add(property1.PropertyName, list); } list.Add(b); b.Owner = target; var source = property2.Source as CpfObject; if (source == null) { throw new Exception("property2.Source必须是CpfObject"); } b.RegisterPropertyChanged(source); return b; } /// /// 右边数据绑定到左边,只传递一次数据 /// /// /// /// public static Binding operator !=(BindingDescribe property1, BindingDescribe property2) { var b = new Binding(property2.Source, property2.PropertyName, property1.PropertyName, BindingMode.OneTime) { Convert = property2.Convert, ConvertBack = property1.Convert }; List list; var target = property1.Source as CpfObject; if (target == null) { throw new Exception("property1.Source必须是CpfObject"); } if (!target.Bindings.binds.TryGetValue(property1.PropertyName, out list)) { list = new List(); target.Bindings.binds.Add(property1.PropertyName, list); } list.Add(b); b.Owner = target; b.SourceToTarget(); return b; } /// /// 右边数据绑定到左边 /// /// /// /// public static Binding operator <=(BindingDescribe property1, BindingDescribe property2) {//可重载一元运算符 +、-、!、~ var b = new Binding(property2.Source, property2.PropertyName, property1.PropertyName, BindingMode.OneWay) { Convert = property2.Convert, ConvertBack = property1.Convert }; List list; var target = property1.Source as CpfObject; if (target == null) { throw new Exception("property1.Source必须是CpfObject"); } if (!target.Bindings.binds.TryGetValue(property1.PropertyName, out list)) { list = new List(); target.Bindings.binds.Add(property1.PropertyName, list); } list.Add(b); b.Owner = target; var source = property2.Source as CpfObject; if (source == null) { throw new Exception("property2.Source必须是CpfObject"); } b.RegisterPropertyChanged(source); b.SourceToTarget(); return b; } /// /// 左边数据绑定到右边 /// /// /// /// public static Binding operator >=(BindingDescribe property1, BindingDescribe property2) {//可重载一元运算符 +、-、!、~ var b = new Binding(property2.Source, property2.PropertyName, property1.PropertyName, BindingMode.OneWayToSource) { Convert = property2.Convert, ConvertBack = property1.Convert }; List list; var target = property1.Source as CpfObject; if (target == null) { throw new Exception("property1.Source必须是CpfObject"); } if (!target.Bindings.binds.TryGetValue(property1.PropertyName, out list)) { list = new List(); target.Bindings.binds.Add(property1.PropertyName, list); } list.Add(b); b.Owner = target; b.TargetToSource(); //property2.Owner.PropertyChanged += b.PropertyChanged; return b; } /// /// 和DataContext的对象的属性双向绑定 /// /// /// DataContext的对象的属性名 /// public static Binding operator ==(BindingDescribe property1, string property2) { var b = new Binding(null, property2, property1.PropertyName, BindingMode.TwoWay) { ConvertBack = property1.Convert }; List list; var target = property1.Source as CpfObject; if (target == null) { throw new Exception("property1.Source必须是CpfObject"); } if (!target.Bindings.binds.TryGetValue(property1.PropertyName, out list)) { list = new List(); target.Bindings.binds.Add(property1.PropertyName, list); } list.Add(b); b.Owner = target; var dc = target.DataContext; if (dc != null) { INotifyPropertyChanged n = dc as INotifyPropertyChanged; if (n != null) { //n.PropertyChanged += b.PropertyChanged; b.RegisterPropertyChanged(n); } b.Source = new WeakReference(dc); b.SourceToTarget(); } return b; } /// /// DataContext的对象的属性数据绑定到左边,只传递一次数据 /// /// /// DataContext的对象的属性名 /// public static Binding operator !=(BindingDescribe property1, string property2) { var b = new Binding(null, property2, property1.PropertyName, BindingMode.OneTime) { ConvertBack = property1.Convert }; List list; var target = property1.Source as CpfObject; if (target == null) { throw new Exception("property1.Source必须是CpfObject"); } if (!target.Bindings.binds.TryGetValue(property1.PropertyName, out list)) { list = new List(); target.Bindings.binds.Add(property1.PropertyName, list); } list.Add(b); b.Owner = target; var dc = target.DataContext; if (dc != null) { b.Source = new WeakReference(dc); b.SourceToTarget(); } return b; } /// /// DataContext的对象的属性数据绑定到左边 /// /// /// DataContext的对象的属性名 /// public static Binding operator <=(BindingDescribe property1, string property2) { var b = new Binding(null, property2, property1.PropertyName, BindingMode.OneWay) { ConvertBack = property1.Convert }; List list; var target = property1.Source as CpfObject; if (target == null) { throw new Exception("property1.Source必须是CpfObject"); } if (!target.Bindings.binds.TryGetValue(property1.PropertyName, out list)) { list = new List(); target.Bindings.binds.Add(property1.PropertyName, list); } list.Add(b); b.Owner = target; var dc = target.DataContext; if (dc != null) { INotifyPropertyChanged n = dc as INotifyPropertyChanged; if (n != null) { //n.PropertyChanged += b.PropertyChanged; b.RegisterPropertyChanged(n); } b.Source = new WeakReference(dc); b.SourceToTarget(); } return b; } /// /// 左边数据绑定到DataContext的对象的属性 /// /// /// DataContext的对象的属性名 /// public static Binding operator >=(BindingDescribe property1, string property2) { var b = new Binding(null, property2, property1.PropertyName, BindingMode.OneWayToSource) { ConvertBack = property1.Convert }; List list; var target = property1.Source as CpfObject; if (target == null) { throw new Exception("property1.Source必须是CpfObject"); } if (!target.Bindings.binds.TryGetValue(property1.PropertyName, out list)) { list = new List(); target.Bindings.binds.Add(property1.PropertyName, list); } list.Add(b); b.Owner = target; var dc = target.DataContext; if (dc != null) { b.Source = new WeakReference(dc); b.TargetToSource(); } return b; } public BindingMode BindingMode { get; set; } = BindingMode.OneWay; public object Source { get; set; } public Action SourceToTargetError { get; set; } public Action TargetToSourceError { get; set; } public Func ConvertBack { get; set; } public static implicit operator BindingDescribe(string sourceProperty) { return new BindingDescribe { PropertyName = sourceProperty }; } public static explicit operator BindingDescribe(Action command) { return new BindingDescribe { Command = command }; } public static implicit operator BindingDescribe((string sourceProperty, BindingMode binding) item) { return new BindingDescribe { PropertyName = item.sourceProperty, BindingMode = item.binding }; } public static implicit operator BindingDescribe((object source, string sourceProperty, BindingMode binding) item) { return new BindingDescribe { PropertyName = item.sourceProperty, Source = item.source, BindingMode = item.binding }; } public static implicit operator BindingDescribe((object source, string sourceProperty) item) { return new BindingDescribe { Source = item.source, PropertyName = item.sourceProperty }; } public static implicit operator BindingDescribe((object source, string sourceProperty, Func convert) item) { return new BindingDescribe { Source = item.source, PropertyName = item.sourceProperty, Convert = item.convert }; } public static implicit operator BindingDescribe((object source, string sourceProperty, BindingMode binding, Func convert) item) { return new BindingDescribe { PropertyName = item.sourceProperty, Source = item.source, BindingMode = item.binding, Convert = item.convert }; } public static implicit operator BindingDescribe((object source, string sourceProperty, BindingMode binding, Func convert, Func convertBack) item) { return new BindingDescribe { PropertyName = item.sourceProperty, Source = item.source, BindingMode = item.binding, Convert = item.convert, ConvertBack = item.convertBack }; } public static implicit operator BindingDescribe((object source, string sourceProperty, BindingMode binding, Func convert, Func convertBack, Action SourceToTargetError, Action TargetToSourceError) item) { return new BindingDescribe { PropertyName = item.sourceProperty, Source = item.source, BindingMode = item.binding, Convert = item.convert, ConvertBack = item.convertBack, SourceToTargetError = item.SourceToTargetError, TargetToSourceError = item.TargetToSourceError }; } public override bool Equals(object obj) { return base.Equals(obj); } public override int GetHashCode() { return base.GetHashCode(); } } }