CPF/CPF/BindingDescribe.cs
2023-11-24 14:11:17 +08:00

397 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace CPF
{
/// <summary>
/// 简化绑定操作
/// </summary>
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<object, object> convert)
{
PropertyName = sourceProperty;
Source = source;
Convert = convert;
}
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert)
{
BindingMode = binding;
PropertyName = sourceProperty;
Source = source;
Convert = convert;
}
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert, Func<object, object> convertBack)
{
BindingMode = binding;
PropertyName = sourceProperty;
Source = source;
Convert = convert;
ConvertBack = convertBack;
}
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert, Func<object, object> convertBack, Action<Binding, object, Exception> SourceToTargetError, Action<Binding, object, Exception> TargetToSourceError)
{
BindingMode = binding;
PropertyName = sourceProperty;
Source = source;
Convert = convert;
ConvertBack = convertBack;
this.SourceToTargetError = SourceToTargetError;
this.TargetToSourceError = TargetToSourceError;
}
public BindingDescribe(Action<CpfObject, object> command)
{
Command = command;
}
/// <summary>
/// 数据绑定的转换
/// </summary>
public Func<object, object> Convert { get; internal set; }
public string PropertyName { get; internal set; }
/// <summary>
/// 简化绑定命令的命令,如果设置了该属性,则使用命令绑定
/// </summary>
public Action<CpfObject, object> Command { get; set; }
//public CpfObject Owner { get; internal set; }
/// <summary>
/// 双向绑定,如果加数据转换器,两个转换器要对称,否则可能出现死循环或者其他错误
/// </summary>
/// <param name="property1"></param>
/// <param name="property2"></param>
/// <returns></returns>
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<Binding> 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<Binding>();
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;
}
/// <summary>
/// 右边数据绑定到左边,只传递一次数据
/// </summary>
/// <param name="property1"></param>
/// <param name="property2"></param>
/// <returns></returns>
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<Binding> 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<Binding>();
target.Bindings.binds.Add(property1.PropertyName, list);
}
list.Add(b);
b.Owner = target;
b.SourceToTarget();
return b;
}
/// <summary>
/// 右边数据绑定到左边
/// </summary>
/// <param name="property1"></param>
/// <param name="property2"></param>
/// <returns></returns>
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<Binding> 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<Binding>();
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;
}
/// <summary>
/// 左边数据绑定到右边
/// </summary>
/// <param name="property1"></param>
/// <param name="property2"></param>
/// <returns></returns>
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<Binding> 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<Binding>();
target.Bindings.binds.Add(property1.PropertyName, list);
}
list.Add(b);
b.Owner = target;
b.TargetToSource();
//property2.Owner.PropertyChanged += b.PropertyChanged;
return b;
}
/// <summary>
/// 和DataContext的对象的属性双向绑定
/// </summary>
/// <param name="property1"></param>
/// <param name="property2">DataContext的对象的属性名</param>
/// <returns></returns>
public static Binding operator ==(BindingDescribe property1, string property2)
{
var b = new Binding(null, property2, property1.PropertyName, BindingMode.TwoWay) { ConvertBack = property1.Convert };
List<Binding> 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<Binding>();
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;
}
/// <summary>
/// DataContext的对象的属性数据绑定到左边只传递一次数据
/// </summary>
/// <param name="property1"></param>
/// <param name="property2">DataContext的对象的属性名</param>
/// <returns></returns>
public static Binding operator !=(BindingDescribe property1, string property2)
{
var b = new Binding(null, property2, property1.PropertyName, BindingMode.OneTime) { ConvertBack = property1.Convert };
List<Binding> 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<Binding>();
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;
}
/// <summary>
/// DataContext的对象的属性数据绑定到左边
/// </summary>
/// <param name="property1"></param>
/// <param name="property2">DataContext的对象的属性名</param>
/// <returns></returns>
public static Binding operator <=(BindingDescribe property1, string property2)
{
var b = new Binding(null, property2, property1.PropertyName, BindingMode.OneWay) { ConvertBack = property1.Convert };
List<Binding> 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<Binding>();
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;
}
/// <summary>
/// 左边数据绑定到DataContext的对象的属性
/// </summary>
/// <param name="property1"></param>
/// <param name="property2">DataContext的对象的属性名</param>
/// <returns></returns>
public static Binding operator >=(BindingDescribe property1, string property2)
{
var b = new Binding(null, property2, property1.PropertyName, BindingMode.OneWayToSource) { ConvertBack = property1.Convert };
List<Binding> 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<Binding>();
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 static BindingDescribe operator *(BindingDescribe property1, string property2)
//{
// return null;
//}
//public static BindingDescribe operator *(BindingDescribe property1, BindingDescribe property2)
//{
// return null;
//}
public BindingMode BindingMode { get; set; } = BindingMode.OneWay;
public object Source { get; set; }
public Action<Binding, object, Exception> SourceToTargetError { get; set; }
public Action<Binding, object, Exception> TargetToSourceError { get; set; }
public Func<object, object> ConvertBack { get; set; }
public static implicit operator BindingDescribe(string sourceProperty)
{
return new BindingDescribe { PropertyName = sourceProperty };
}
public static explicit operator BindingDescribe(Action<CpfObject, object> 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<object, object> 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<object, object> 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<object, object> convert, Func<object, object> 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<object, object> convert, Func<object, object> convertBack, Action<Binding, object, Exception> SourceToTargetError, Action<Binding, object, Exception> 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();
}
}
}