mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-06-28 13:34:09 +08:00
507 lines
21 KiB
C#
507 lines
21 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using System.ComponentModel;
|
||
using System.Linq.Expressions;
|
||
|
||
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;
|
||
//}
|
||
/// <summary>
|
||
/// 设置绑定
|
||
/// </summary>
|
||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||
/// <param name="sourceProperty"></param>
|
||
/// <param name="binding"></param>
|
||
public BindingDescribe(object source, string sourceProperty, BindingMode binding)
|
||
{
|
||
PropertyName = sourceProperty;
|
||
BindingMode = binding;
|
||
Source = source;
|
||
}
|
||
/// <summary>
|
||
/// 设置绑定
|
||
/// </summary>
|
||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||
/// <param name="sourceProperty"></param>
|
||
public BindingDescribe(object source, string sourceProperty)
|
||
{
|
||
PropertyName = sourceProperty;
|
||
Source = source;
|
||
}
|
||
///// <summary>
|
||
///// 设置绑定
|
||
///// </summary>
|
||
///// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||
///// <param name="sourceProperty"></param>
|
||
///// <param name="convert"></param>
|
||
//public BindingDescribe(object source, string sourceProperty, Func<object, object> convert)
|
||
//{
|
||
// PropertyName = sourceProperty;
|
||
// Source = source;
|
||
// Convert = convert;
|
||
//}
|
||
/// <summary>
|
||
/// 设置绑定
|
||
/// </summary>
|
||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||
/// <param name="sourceProperty"></param>
|
||
/// <param name="binding"></param>
|
||
/// <param name="convert"></param>
|
||
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert)
|
||
{
|
||
BindingMode = binding;
|
||
PropertyName = sourceProperty;
|
||
Source = source;
|
||
Convert = convert;
|
||
}
|
||
/// <summary>
|
||
/// 设置绑定
|
||
/// </summary>
|
||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||
/// <param name="sourceProperty"></param>
|
||
/// <param name="binding"></param>
|
||
/// <param name="convert"></param>
|
||
/// <param name="convertBack"></param>
|
||
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert = null, Func<object, object> convertBack = null)
|
||
{
|
||
BindingMode = binding;
|
||
PropertyName = sourceProperty;
|
||
Source = source;
|
||
Convert = convert;
|
||
ConvertBack = convertBack;
|
||
}
|
||
/// <summary>
|
||
/// 设置绑定
|
||
/// </summary>
|
||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||
/// <param name="sourceProperty"></param>
|
||
/// <param name="binding"></param>
|
||
/// <param name="convert"></param>
|
||
/// <param name="convertBack"></param>
|
||
/// <param name="SourceToTargetError"></param>
|
||
/// <param name="TargetToSourceError"></param>
|
||
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert = null, Func<object, object> convertBack = null, Action<Binding, object, Exception> SourceToTargetError = null, Action<Binding, object, Exception> TargetToSourceError = null)
|
||
{
|
||
BindingMode = binding;
|
||
PropertyName = sourceProperty;
|
||
Source = source;
|
||
Convert = convert;
|
||
ConvertBack = convertBack;
|
||
this.SourceToTargetError = SourceToTargetError;
|
||
this.TargetToSourceError = TargetToSourceError;
|
||
}
|
||
|
||
public BindingDescribe(Func<UIElement, UIElement> find, string sourcePropertyName, BindingMode bindingMode = BindingMode.OneWay, Func<object, object> convert = null, Func<object, object> convertBack = null, Action<Binding, object, Exception> SourceToTargetError = null, Action<Binding, object, Exception> TargetToSourceError = null)
|
||
{
|
||
BindingMode = bindingMode;
|
||
PropertyName = sourcePropertyName;
|
||
Source = find;
|
||
//Find = find;
|
||
Convert = convert;
|
||
ConvertBack = convertBack;
|
||
this.SourceToTargetError = SourceToTargetError;
|
||
this.TargetToSourceError = TargetToSourceError;
|
||
}
|
||
|
||
//public BindingDescribe(CommandDescribe command)
|
||
//{
|
||
// Command = command;
|
||
//}
|
||
|
||
/// <summary>
|
||
/// 数据绑定的转换
|
||
/// </summary>
|
||
public Func<object, object> Convert { get; internal set; }
|
||
|
||
public string PropertyName { get; internal set; }
|
||
/// <summary>
|
||
/// 简化绑定命令的命令,如果设置了该属性,则使用命令绑定
|
||
/// </summary>
|
||
public CommandDescribe Command { get; set; }
|
||
/// <summary>
|
||
/// 简化触发器设置
|
||
/// </summary>
|
||
public CPF.Styling.TriggerDescribe Trigger { 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 Func<UIElement, UIElement> Find { 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 implicit operator BindingDescribe(CommandDescribe command)
|
||
{
|
||
return new BindingDescribe { Command = command };
|
||
}
|
||
public static implicit operator BindingDescribe(CPF.Styling.TriggerDescribe trigger)
|
||
{
|
||
return new BindingDescribe { Trigger = trigger };
|
||
}
|
||
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();
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 命令绑定
|
||
/// </summary>
|
||
public class CommandDescribe
|
||
{
|
||
public Action<CpfObject, object> Action { get; set; }
|
||
|
||
public string MethodName { get; set; }
|
||
public object[] Parameters { get; set; }
|
||
|
||
public object Target { get; set; }
|
||
|
||
public Func<UIElement, UIElement> Find { get; set; }
|
||
/// <summary>
|
||
/// 用委托定义个命令绑定
|
||
/// </summary>
|
||
/// <param name="command"></param>
|
||
public CommandDescribe(Action<CpfObject, object> command)
|
||
{
|
||
Action = command;
|
||
}
|
||
/// <summary>
|
||
/// 定义个命令绑定
|
||
/// </summary>
|
||
/// <param name="methodName"></param>
|
||
/// <param name="obj"></param>
|
||
/// <param name="ps"></param>
|
||
public CommandDescribe(string methodName, object obj = null, params object[] ps)
|
||
{
|
||
MethodName = methodName;
|
||
Parameters = ps;
|
||
Target = obj;
|
||
}
|
||
/// <summary>
|
||
/// 查找元素并绑定命令
|
||
/// </summary>
|
||
/// <param name="methodName"></param>
|
||
/// <param name="find"></param>
|
||
/// <param name="ps"></param>
|
||
public CommandDescribe(string methodName, Func<UIElement, UIElement> find, params object[] ps)
|
||
{
|
||
MethodName = methodName;
|
||
Parameters = ps;
|
||
Find = find;
|
||
}
|
||
}
|
||
}
|