diff --git a/CPF/CpfObject - 副本.cs b/CPF/CpfObject - 副本.cs deleted file mode 100644 index c41f074..0000000 --- a/CPF/CpfObject - 副本.cs +++ /dev/null @@ -1,2812 +0,0 @@ -using System; -using System.ComponentModel; -using System.Collections.Generic; -using System.Text; -using System.Runtime.CompilerServices; -using System.Reflection; -using CPF.Reflection; -using System.Linq; -using System.Linq.Expressions; -using System.Diagnostics; -using CPF.Styling; -using CPF.Animation; -using System.Collections.Concurrent; -using System.Runtime.InteropServices; -using System.Collections; - -namespace CPF -{ - /// - /// 默认所有属性都是依赖属性,如果不想作为依赖属性,属性上加上[NotCpfProperty]特性。不能使用new来覆盖已经定义为依赖属性的属性,最多255个依赖属性 - /// - public class CpfObject : INotifyPropertyChanged, IDisposable, ICloneable, Design.ISerializerCode, IObservable> - { - static ConcurrentDictionary> typeCache = new ConcurrentDictionary>(); - static ConcurrentDictionary typePropertyCache = new ConcurrentDictionary(); - static ConcurrentDictionary> inheritsProperties = new ConcurrentDictionary>(); - static Dictionary> propertyChangedMethods = new Dictionary>(); - - static KeyValuePair>[] saveTypeCache; - static KeyValuePair[] saveTypePropertyCache; - static KeyValuePair>[] saveInheritsProperties; - static KeyValuePair>[] savePropertyChangedMethods; - public static void SetTypeCache() - { - saveTypeCache = typeCache.ToArray(); - saveTypePropertyCache = typePropertyCache.ToArray(); - saveInheritsProperties = inheritsProperties.ToArray(); - FastReflectionExtensions.SetTypeCache(); - savePropertyChangedMethods = propertyChangedMethods.ToArray(); - } - public static void RecoveryTypeCache() - { - if (saveTypeCache != null) - { - typeCache.Clear(); - foreach (var item in saveTypeCache) - { - typeCache.TryAdd(item.Key, item.Value); - } - saveTypeCache = null; - } - if (saveTypePropertyCache != null) - { - typePropertyCache.Clear(); - foreach (var item in saveTypePropertyCache) - { - typePropertyCache.TryAdd(item.Key, item.Value); - } - saveTypePropertyCache = null; - } - if (saveInheritsProperties != null) - { - inheritsProperties.Clear(); - foreach (var item in saveInheritsProperties) - { - inheritsProperties.TryAdd(item.Key, item.Value); - } - saveInheritsProperties = null; - } - if (savePropertyChangedMethods != null) - { - propertyChangedMethods.Clear(); - foreach (var item in savePropertyChangedMethods) - { - propertyChangedMethods.Add(item.Key, item.Value); - } - savePropertyChangedMethods = null; - } - FastReflectionExtensions.RecoveryTypeCache(); - } - - Dictionary objInfo; - PropertyMetadataAttribute[] propertyInfos; - //EffectiveValue[] values; - byte[] valueIndexs; - _List valueList = new _List(); - - internal HybridDictionary attachedValues; - /// - /// 继承属性的特性 - /// - internal HashSet inheritsPropertyName; - - AttachedProperties attached; - /// - /// 用于设置附加属性,和绑定附加属性 - /// - [Category("绑定")] - [Description("用于设置附加属性,一般控件上会有附加属性分组,那边设置就行,可以不需要在这里设置。")] - [NotCpfProperty] - public AttachedProperties Attacheds - { - get - { - if (attached == null) - { - attached = new AttachedProperties(this); - } - return attached; - } - } - - AttachedNotify attachedNotify; - internal AttachedNotify AttachedNotify - { - get - { - if (attachedNotify == null) - { - attachedNotify = new AttachedNotify(this); - } - return attachedNotify; - } - } - - internal Bindings bindings; - /// - /// 设置绑定 - /// - [NotCpfProperty] - [Category("绑定")] - [Description("设置数据绑定")] - public Bindings Bindings - { - get - { - if (bindings == null) - { - bindings = new Bindings(this); - } - return bindings; - } - } - - internal Commands commands; - /// - /// 设置命令 - /// - [NotCpfProperty] - [Category("绑定")] - [Description("设置命令绑定")] - public Commands Commands - { - get - { - if (commands == null) - { - commands = new Commands(this); - } - return commands; - } - } - - Type type; - /// - /// 设置绑定 - /// - /// 需要绑定的属性名 - ///// 绑定的属性值转换到源对象的属性值 - /// - [NotCpfProperty] - public BindingDescribe this[string propertyName] - { - get { return new BindingDescribe { Source = this, PropertyName = propertyName }; } - set - { - Bindings.Add(propertyName, value.PropertyName, value.Source, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError); - } - } - - public CpfObject() - { - type = this.GetType(); - //Threading.Dispatcher.MainThread.VerifyAccess(); - if (!typeCache.TryGetValue(type, out objInfo)) - { - //typeNames.Add(type.Name, type); - objInfo = new Dictionary(); - typeCache.TryAdd(type, objInfo); - List propertyList = new List(); - var list = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); - - list = list.OrderBy(a => a.DeclaringType, new TypeCompar()).ThenBy(a => a.MetadataToken).ToArray(); - - OverrideMetadata om = new OverrideMetadata(); - OnOverrideMetadata(om); - var not = typeof(NotCpfProperty); - var pm = typeof(PropertyMetadataAttribute); - var cm = typeof(ComputedAttribute); - byte id = 0; - //List<(PropertyInfo, ComputedAttribute[])> computeProterty = new List<(PropertyInfo, ComputedAttribute[])>(); - List computeProterty = new List(); - foreach (var item in list) - { - var nots = item.GetCustomAttributes(not, true); - if (nots.Length == 0) - { - var ass = item.GetCustomAttributes(pm, true); - - PropertyMetadataAttribute a; - if (!om.list.TryGetValue(item.Name, out a)) - { - if (ass.Length > 0) - { - a = (PropertyMetadataAttribute)ass[0]; - } - else - { - a = new PropertyMetadataAttribute(); - a.DefaultValue = item.PropertyType.IsValueType ? Activator.CreateInstance(item.PropertyType) : null; ; - } - } - a.PropertyType = item.PropertyType; - a.PropertyName = item.Name; - if (a.DefaultValue != null) - { - var t = a.DefaultValue.GetType(); - if (t != a.PropertyType && !a.PropertyType.IsAssignableFrom(t)) - { - throw new InvalidCastException($"{type.Name}的属性{item.Name}的默认值类型不对"); - } - } - a.Id = id; - id++; - objInfo.Add(item.Name, a); - propertyList.Add(a); - var ca = item.GetCustomAttributes(cm, true); - if (ca.Length > 0) - { - //computeProterty.Add((item, (ComputedAttribute[])ca)); - computeProterty.Add(new ComputeProtertyInfo { Property = item, NoticeProperties = ((ComputedAttribute[])ca)[0].Properties }); - } - } - } - - typePropertyCache.TryAdd(type, propertyList.ToArray()); - - var l = new HashSet(); - foreach (var item in objInfo) - { - if (item.Value is UIPropertyMetadataAttribute attribute && attribute.Inherits) - { - l.Add(attribute.PropertyName); - } - } - if (l.Count == 0) - { - l = null; - } - inheritsProperties.TryAdd(type, l); - - //Type tt = typeof(PropertyChangedAttribute); - //var ms = type.FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, (a, b) => a.CustomAttributes.Any(c => c.AttributeType == tt), null); - foreach (MethodInfo item in Methods(type)) - { - try - { - var attrs = item.GetCustomAttributes(typeof(PropertyChangedAttribute), true); - foreach (PropertyChangedAttribute attr in attrs) - { - if (!objInfo.TryGetValue(attr.PropertyName, out PropertyMetadataAttribute attribute)) - { - throw new Exception("不存在属性:" + attr.PropertyName); - } - if (attribute.actions == null) - { - attribute.actions = new List(); - } - var instanceParameter = Expression.Parameter(typeof(CpfObject), "instance"); - var newValueParameter = Expression.Parameter(typeof(object), "newValue"); - var oldValueParameter = Expression.Parameter(typeof(object), "oldValue"); - var attributeParameter = Expression.Parameter(typeof(PropertyMetadataAttribute), "attribute"); - var instanceCast = Expression.Convert(instanceParameter, item.ReflectedType); - var methodCall = Expression.Call(instanceCast, item, new ParameterExpression[] { newValueParameter, oldValueParameter, attributeParameter }); - - var lambda = Expression.Lambda( - methodCall, instanceParameter, newValueParameter, oldValueParameter, attributeParameter); - - var execute = lambda.Compile(); - - attribute.actions.Add(execute); - } - } - catch (Exception e) - { - throw new Exception("绑定属性通知出错,检查方法参数类型和返回值类型:" + item.Name, e); - } - } - - OnInitializeComputeProterty(computeProterty.Where(a => a.NoticeProperties == null)); - - foreach (var item in computeProterty) - { - //if (item.Item2[0].Properties != null && item.Item2[0].Properties.Length > 0) - if (item.NoticeProperties == null && item.Tokens != null) - { - List ps = new List(); - foreach (var t in item.Tokens) - { - var p = list.FirstOrDefault(a => a.MetadataToken == t); - if (p != null) - { - ps.Add(p.Name); - } - } - item.NoticeProperties = ps.ToArray(); - } - if (item.NoticeProperties != null && item.NoticeProperties.Length > 0) - { - //foreach (var p in item.Item2[0].Properties) - foreach (var p in item.NoticeProperties) - { - if (!string.IsNullOrWhiteSpace(p)) - { - if (!objInfo.TryGetValue(p, out PropertyMetadataAttribute attribute)) - { - throw new Exception("不存在属性:" + p); - } - if (attribute.actions == null) - { - attribute.actions = new List(); - } - var instanceParameter = Expression.Parameter(typeof(CpfObject), "instance"); - var newValueParameter = Expression.Parameter(typeof(object), "newValue"); - var oldValueParameter = Expression.Parameter(typeof(object), "oldValue"); - var attributeParameter = Expression.Parameter(typeof(PropertyMetadataAttribute), "attribute"); - //var instanceCast = Expression.Convert(instanceParameter, item.Item1.ReflectedType); - var instanceCast = Expression.Convert(instanceParameter, item.Property.ReflectedType); - var propValue = Expression.Property(instanceCast, item.Property); - var methodCall = Expression.Call(instanceCast, setValue.MakeGenericMethod(typeof(object)), propValue, Expression.Constant(item.Property.Name)); - var lambda = Expression.Lambda( - methodCall, instanceParameter, newValueParameter, oldValueParameter, attributeParameter); - - var execute = lambda.Compile(); - - attribute.actions.Add(execute); - } - } - } - } - } - //values = new EffectiveValue[objInfo.Count]; - propertyInfos = typePropertyCache[type]; - - if (objInfo.Count > 255) - { - throw new Exception(type + "类型属性数量不能超过255"); - } - //valueIndexs = new ByteArray((byte)objInfo.Count); - valueIndexs = new byte[objInfo.Count]; - inheritsPropertyName = inheritsProperties[type]; - } - class TypeCompar : IComparer - { - public int Compare(Type x, Type y) - { - if (x == y) - { - return 0; - } - if (x.IsAssignableFrom(y)) - { - return -1; - } - return 1; - } - } - static MethodInfo setValue = typeof(CpfObject).GetMethod(nameof(SetValue)); - - static IEnumerable Methods(Type type) - { - if (!propertyChangedMethods.TryGetValue(type, out List methods)) - { - methods = new List(); - Type t = typeof(PropertyChangedAttribute); - //var ms = type.FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, (a, b) => a.CustomAttributes.Any(c => c.AttributeType == t), null); - var ms = type.FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, (a, b) => - { - var alist = a.GetCustomAttributes(t, true); - return alist != null && alist.Length > 0; - }, null); - foreach (MethodInfo item in ms) - { - if (!item.IsStatic) - { - methods.Add(item); - } - } - propertyChangedMethods.Add(type, methods); - } - foreach (var item in methods) - { - yield return item; - } - if (type.BaseType != typeof(object)) - { - foreach (var item in Methods(type.BaseType)) - { - yield return item; - } - } - } - /// - /// 用于初始化计算属性,请不要调用和重写,内部使用 - /// - /// - protected virtual void OnInitializeComputeProterty(IEnumerable computeProterties) - { - //foreach (var item in computeProterties) - //{ - // if (item.Property.Name == "通知属性1") - // { - // item.NoticeProperties = new string[] { "属性1", "属性2" }; - - // item.Tokens = new int[] { };//如果没有解析到属性名,NoticeProperties不要设置 - // } - //} - } - - /// - /// 该类型的第一个对象构造的时候调用,重写属性元数据,一般重写属性的代码写在base.OnOverrideMetadata后面 - /// - /// - protected virtual void OnOverrideMetadata(OverrideMetadata overridePropertys) - { - - } - - //[PropertyMetadata(null)] - //public string Name - //{ - // get { return GetValue(); } - // set { SetValue(value); } - //} - /// - /// 绑定的数据上下文 - /// - [Category("绑定")] - [Description("绑定的数据上下文")] - [UIPropertyMetadata(null, true)] - public virtual object DataContext - { - get { return GetValue(); } - set { SetValue(value); } - } - - /// - /// 绑定的命令上下文 - /// - [Category("绑定")] - [Description("绑定的命令上下文")] - [UIPropertyMetadata(null, true)] - public virtual object CommandContext - { - get { return GetValue(); } - set { SetValue(value); } - } - - /// - /// 当前对象的类型 - /// - [NotCpfProperty] - [Browsable(false)] - public Type Type - { - get - { - //if (type == null) - //{ - // type = this.GetType(); - //} - return type; - } - } - /// - /// 附加属性更改时发生 - /// - /// 所注册在的类型 - /// - /// - /// - /// - protected virtual void OnAttachedChanged(Type ownerType, string propertyName, object defaultValue, object oldValue, object newValue) - { - if (attachedNotify != null) - { - attachedNotify.OnPropertyChanged(propertyName, oldValue, newValue, attachedNotify.GetPropertyMetadata(propertyName)); - } - } - - /// - /// 注册附加属性 - /// - /// - /// 默认值 - /// 所注册在的类型 - /// 属性变化回调 - /// 属性名一般不用设置,VS自动设置 - /// - public static Attached RegisterAttached(Value defaultValue, Type ownerType, AttachedPropertyChanged propertyChanged = null, [CallerMemberName] string propertyName = null) - { - var func = new Attached((obj, value) => - { - if (obj.attachedValues == null) - { - obj.attachedValues = new HybridDictionary(); - } - if (obj.attachedValues.TryGetValue(ownerType.Name + "." + propertyName, out object v)) - { - if (value.HasValue) - { - obj.attachedValues.Remove(ownerType.Name + "." + propertyName); - } - } - else - { - v = defaultValue; - } - if (value.HasValue) - { - object newValue = value.Value; - propertyChanged?.Invoke(obj, propertyName, defaultValue, v, ref newValue); - obj.attachedValues.Add(ownerType.Name + "." + propertyName, value.Value); - obj.OnAttachedChanged(ownerType, propertyName, defaultValue, v, newValue); - v = newValue; - } - return (Value)v; - }); - return func; - } - ///// - ///// 当修改附加属性的时候 - ///// - ///// 被附加的对象 - ///// - ///// - ///// - ///// - //protected virtual void OnAttachedChanged(CPFObject @object, string propertyName, object defaultValue, object oldValue, ref object newValue) - //{ - - //} - - bool TryGetValue(string propertyName, out PropertyMetadataAttribute attribute, out EffectiveValue value) - { - //if (disposedValue) - //{ - // value = null; - // attribute = null; - // return false; - //} - if (!objInfo.TryGetValue(propertyName, out attribute)) - { - value = null; - return false; - } - //value = values[attribute.Id]; - value = GetEffectiveValue(attribute); - return value != null; - } - - EffectiveValue GetEffectiveValue(PropertyMetadataAttribute attribute) - { - var id = valueIndexs[attribute.Id] - 1;//因为默认值就是0,所以要-1 - if (id > -1 && id < valueList.Count) - { - return valueList[id]; - } - return null; - } - - void SetValue(PropertyMetadataAttribute attribute, EffectiveValue value) - { - var id = valueIndexs[attribute.Id] - 1; - if (id > -1 && id < valueList.Count) - { - valueList[id] = value; - } - else - { - valueList.Add(value); - valueIndexs[attribute.Id] = valueList.Count; - } - } - - /// - /// 获取有LocalValue的属性和值 - /// - /// - public IEnumerable<(string, object)> GetHasLocalValueProperties() - { - foreach (var item in objInfo) - { - //var value = values[item.Value.Id]; - var value = GetEffectiveValue(item.Value); - if (value != null && value.LocalValue.HasValue) - { - yield return (item.Key, value.LocalValue.Value); - } - } - } - - /// - /// 设置属性值 - /// - /// - /// - /// - /// 设置属性值是否成功 - public virtual bool SetValue(T value, [CallerMemberName] string propertyName = null) - { - if (string.IsNullOrEmpty(propertyName)) - { - throw new Exception("propertyName不能为空"); - } - //Threading.Dispatcher.MainThread.VerifyAccess(); - object v = value; - if (OnSetValue(propertyName, ref v)) - { - //bool ex = true; - object oldValue; - EffectiveValue oValue; - PropertyMetadataAttribute p; - - if (!TryGetValue(propertyName, out p, out oValue)) - { - if (p == null) - { - //throw new Exception("未找到该属性的元数据:" + propertyName); - return false; - } - oldValue = OnGetDefaultValue(p); - } - else - { - //p = oValue.PropertyMetadata; - if (!oValue.GetLocalValue(out oldValue)) - { - oldValue = OnGetDefaultValue(p); - } - } - if (value != null) - { - var t = value.GetType(); - if (t != p.PropertyType && !p.PropertyType.IsAssignableFrom(t)) - { - v = value.ConvertTo(p.PropertyType); - } - } - //if ((oldValue == null && v != null) || (oldValue != null && v == null) || (oldValue != null && !oldValue.Equals(v))) - if (!oldValue.Equal(v)) - { - if (oValue == null) - { - oValue = new EffectiveValue(); - //values[p.Id] = oValue; - SetValue(p, oValue); - } - oValue.LocalValue.HasValue = true; - oValue.LocalValue.Value = v; - oValue.ClearStyleValues(); - if (!oValue.HasStyleValue()) - { - OnSetValue(propertyName, p, ValueForm.Property, v); - OnPropertyChanged(propertyName, oldValue, v, p); - } - } - else if (oldValue == null && oValue == null && v == null && (propertyName == nameof(DataContext) || propertyName == nameof(CommandContext))) - { - oValue = new EffectiveValue(); - //values[p.Id] = oValue; - SetValue(p, oValue); - oValue.LocalValue.HasValue = true; - } - return true; - } - return false; - } - /// - /// 内部使用,请勿调用 - /// - /// - /// - /// - protected virtual bool SetValue(object value, in byte propertyIndex) - { - var p = propertyInfos[propertyIndex]; - object v = value; - var propertyName = p.PropertyName; - if (OnSetValue(propertyName, ref v)) - { - //bool ex = true; - object oldValue; - EffectiveValue oValue; - - if (!TryGetValue(propertyName, out p, out oValue)) - { - if (p == null) - { - //throw new Exception("未找到该属性的元数据:" + propertyName); - return false; - } - oldValue = OnGetDefaultValue(p); - } - else - { - //p = oValue.PropertyMetadata; - if (!oValue.GetLocalValue(out oldValue)) - { - oldValue = OnGetDefaultValue(p); - } - } - if (value != null) - { - var t = value.GetType(); - if (t != p.PropertyType && !p.PropertyType.IsAssignableFrom(t)) - { - v = value.ConvertTo(p.PropertyType); - } - } - //if ((oldValue == null && v != null) || (oldValue != null && v == null) || (oldValue != null && !oldValue.Equals(v))) - if (!oldValue.Equal(v)) - { - if (oValue == null) - { - oValue = new EffectiveValue(); - //values[p.Id] = oValue; - SetValue(p, oValue); - } - oValue.LocalValue.HasValue = true; - oValue.LocalValue.Value = v; - oValue.ClearStyleValues(); - if (!oValue.HasStyleValue()) - { - OnSetValue(propertyName, p, ValueForm.Property, v); - OnPropertyChanged(propertyName, oldValue, v, p); - } - } - else if (oldValue == null && oValue == null && v == null && (propertyName == nameof(DataContext) || propertyName == nameof(CommandContext))) - { - oValue = new EffectiveValue(); - //values[p.Id] = oValue; - SetValue(p, oValue); - oValue.LocalValue.HasValue = true; - } - return true; - } - return false; - } - - internal void SetStyleValue(string propertyName, Style style, object value) - { - if (OnSetValue(propertyName, ref value)) - { - EffectiveValue oValue; - PropertyMetadataAttribute p; - if (!TryGetValue(propertyName, out p, out oValue)) - { - if (p == null) - { - throw new Exception("未找到该属性的元数据:" + propertyName); - } - //oValue.PropertyMetadata = p; - oValue = new EffectiveValue(); - //values[p.Id] = oValue; - SetValue(p, oValue); - } - try - { - if (oValue.styleValues == null || oValue.styleValues.Count == 0 || oValue.styleValues[oValue.styleValues.Count - 1].Style.Index < style.Index) - { - object oldValue; - if (!oValue.GetValue(out oldValue)) - { - oldValue = OnGetDefaultValue(p); - } - - oValue.SetStyleValue(style, value); - if ((oldValue == null && value != null) || (oldValue != null && value == null) || (oldValue != null && !oldValue.Equals(value))) - { - OnSetValue(propertyName, p, ValueForm.Style, value); - OnPropertyChanged(propertyName, oldValue, value, p); - } - } - else - { - oValue.SetStyleValue(style, value); - oValue.styleValues.Sort(styleSort); - } - } - catch (Exception e) - { - throw new Exception(this + " " + style.Selector.ToString() + " " + style.Index, e); - } - } - } - - static StyleSort styleSort = new StyleSort(); - class StyleSort : IComparer - { - public int Compare(StyleValue x, StyleValue y) - { - return x.Style.Index - y.Style.Index; - } - } - - internal void SetAnimationValue(string propertyName, Storyboard Storyboard, object value) - { - if (OnSetValue(propertyName, ref value)) - { - object oldValue; - EffectiveValue oValue; - PropertyMetadataAttribute p; - if (!TryGetValue(propertyName, out p, out oValue)) - { - if (p == null) - { - throw new Exception("未找到该属性的元数据:" + propertyName); - } - //oValue.PropertyMetadata = p; - oValue = new EffectiveValue(); - //values[p.Id] = oValue; - SetValue(p, oValue); - } - //else - //{ - // p = oValue.PropertyMetadata; - //} - if (!oValue.GetValue(out oldValue)) - { - oldValue = OnGetDefaultValue(p); - } - - oValue.SetAnimationValue(Storyboard, value); - if ((oldValue == null && value != null) || (oldValue != null && value == null) || (oldValue != null && !oldValue.Equals(value))) - { - OnSetValue(propertyName, p, ValueForm.Animation, value); - OnPropertyChanged(propertyName, oldValue, value, p); - } - } - } - internal void SetTriggerValue(string propertyName, Trigger Trigger, object value) - { - if (OnSetValue(propertyName, ref value)) - { - object oldValue; - EffectiveValue oValue; - PropertyMetadataAttribute p; - if (!TryGetValue(propertyName, out p, out oValue)) - { - if (p == null) - { - throw new Exception("未找到该属性的元数据:" + propertyName); - } - //oValue.PropertyMetadata = p; - oValue = new EffectiveValue(); - //values[p.Id] = oValue; - SetValue(p, oValue); - } - //else - //{ - // p = oValue.PropertyMetadata; - //} - if (value != null) - { - var vType = value.GetType(); - if (vType != p.PropertyType && !p.PropertyType.IsAssignableFrom(vType)) - { - value = value.ConvertTo(p.PropertyType); - } - } - if (!oValue.GetValue(out oldValue)) - { - oldValue = OnGetDefaultValue(p); - } - oValue.SetTriggerValue(Trigger, value); - if (Trigger.SetPropertys == null) - { - Trigger.SetPropertys = new HybridDictionary>(); - } - if (!Trigger.SetPropertys.TryGetValue(this, out List ps)) - { - ps = new List(); - Trigger.SetPropertys.Add(this, ps); - } - ps.Add(propertyName); - if ((oldValue == null && value != null) || (oldValue != null && value == null) || (oldValue != null && !oldValue.Equals(value))) - { - OnSetValue(propertyName, p, ValueForm.Trigger, value); - OnPropertyChanged(propertyName, oldValue, value, p); - } - } - } - - [PropertyChanged(nameof(DataContext))] - void RegisterRenderDataContext(object newValue, object oldValue, PropertyMetadataAttribute attribute) - { - if (oldValue != null) - { - if (bindings != null) - { - foreach (var item in bindings.binds) - { - foreach (var i in item.Value) - { - if (i.IsDataContext && i.Source != null && i.Source.IsAlive) - { - INotifyPropertyChanged n = i.Source.Target as INotifyPropertyChanged; - if (n != null) - { - //n.PropertyChanged -= i.PropertyChanged; - i.CancellationPropertyChanged(n); - } - i.Source = null; - } - } - } - } - } - //if (newValue != null) - { - if (bindings != null) - { - foreach (var item in bindings.binds) - { - foreach (var i in item.Value) - { - if (i.IsDataContext) - { - if (newValue != null) - { - i.Source = new WeakReference(newValue); - } - else - { - i.Source = null; - } - if (i.BindingMode == BindingMode.OneWay || i.BindingMode == BindingMode.TwoWay) - { - INotifyPropertyChanged no = newValue as INotifyPropertyChanged; - if (no != null) - { - i.RegisterPropertyChanged(no); - } - } - if (i.BindingMode != BindingMode.OneWayToSource) - { - i.SourceToTarget(); - } - else - { - if (newValue != null) - { - i.TargetToSource(); - } - } - } - } - } - } - } - } - - /// - /// 一般不建议在这里处理属性通知,建议用PropertyChanged特性来注册属性通知。 - /// - /// - /// - /// - /// - protected virtual void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata) - { - if (propertyMetadata.actions != null) - { - //foreach (var item in propertyMetadata.actions) - //{ - // item(this, newValue, oldValue, propertyMetadata); - //} - for (int i = 0; i < propertyMetadata.actions.Count; i++) - { - propertyMetadata.actions[i](this, newValue, oldValue, propertyMetadata); - } - } - //if (propertyName == nameof(DataContext)) - //{ - // if (oldValue != null) - // { - // if (bindings != null) - // { - // foreach (var item in bindings.binds) - // { - // foreach (var i in item.Value) - // { - // if (i.IsDataContext && i.Source != null && i.Source.IsAlive) - // { - // INotifyPropertyChanged n = i.Source.Target as INotifyPropertyChanged; - // if (n != null) - // { - // //n.PropertyChanged -= i.PropertyChanged; - // i.CancellationPropertyChanged(n); - // } - // i.Source = null; - // } - // } - // } - // } - // } - // if (newValue != null) - // { - // if (bindings != null) - // { - // foreach (var item in bindings.binds) - // { - // foreach (var i in item.Value) - // { - // if (i.IsDataContext) - // { - // i.Source = new WeakReference(newValue); - // if (i.BindingMode == BindingMode.OneWay || i.BindingMode == BindingMode.TwoWay) - // { - // INotifyPropertyChanged no = newValue as INotifyPropertyChanged; - // if (no != null) - // { - // i.RegisterPropertyChanged(no); - // } - // } - // if (i.BindingMode != BindingMode.OneWayToSource) - // { - // i.SourceToTarget(); - // } - // else - // { - // i.TargetToSource(); - // } - // } - // } - // } - // } - // } - //} - - var cpc = new CPFPropertyChangedEventArgs { NewValue = newValue, OldValue = oldValue, PropertyMetadata = propertyMetadata, PropertyName = propertyName }; - if (bindings != null && bindings.binds.TryGetValue(propertyName, out List list)) - { - SetBinding(list); - } - if (commands != null && commands.commands.TryGetValue(propertyName, out List list1)) - { - SetCommand(cpc, list1); - } - - RaiseEvent(cpc, strPropertyChanged); - - //PropertyChangedEventHandler handler = (PropertyChangedEventHandler)Events["INotifyPropertyChanged"]; - NotifyPropertyChanged(propertyName); - } - static string strPropertyChanged = "PropertyChanged"; - - /// - /// 触发INotifyPropertyChanged的PropertyChanged事件 - /// - /// - public void NotifyPropertyChanged(string propertyName) - { - if (propertyChangedEventHandler != null) - { - propertyChangedEventHandler(this, new PropertyChangedEventArgs(propertyName)); - //propertyChangedEventHandler.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - } - - private void SetCommand(in CPFPropertyChangedEventArgs eventArgs, List list1) - { - foreach (var item in list1) - { - if (item.Action == null) - { - var objs = new List(); - object v = null; - if (item.Target != null) - { - v = item.Target.Target; - objs.Add(v); - } - //else if (item.Relation != null && this is UIElement) - //{ - // objs.AddRange(item.Relation.Query(this as UIElement)); - //} - else - { - v = CommandContext; - if (v != null) - { - objs.Add(v); - } - } - //var v = GetValue(item.PropertyName); - foreach (var vv in objs) - { - object[] ps = new object[item.Params == null ? 0 : item.Params.Length]; - if (item.Params != null && item.Params.Length > 0) - { - item.Params.CopyTo(ps, 0); - //ps = item.Params; - for (int i = 0; i < ps.Length; i++) - { - var p = ps[i]; - if (p is CommandParameter) - { - if ((CommandParameter)p == CommandParameter.PropertyValue) - { - ps[i] = eventArgs.NewValue; - } - else if ((CommandParameter)p == CommandParameter.OldPropertyValue) - { - ps[i] = eventArgs.OldValue; - } - else if ((CommandParameter)p == CommandParameter.PropertyMetadata) - { - ps[i] = eventArgs.PropertyMetadata; - } - else if ((CommandParameter)p == CommandParameter.EventArgs) - { - ps[i] = eventArgs; - } - else if ((CommandParameter)p == CommandParameter.EventSender) - { - ps[i] = this; - } - } - } - } - //var m = vv.GetType().GetMethod(item.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - //if (m == null) - //{ - // throw new Exception("未找到该方法 " + item.MethodName); - //} - //m.FastInvoke(vv, ps); - vv.Invoke(item.MethodName, ps); - } - } - else - { - item.Action(this, eventArgs); - } - } - } - - private static void SetBinding(List tlist) - { - foreach (var item in tlist) - { - if (item.Source != null && (item.BindingMode == BindingMode.TwoWay || item.BindingMode == BindingMode.OneWayToSource)) - { - if (item.Source.IsAlive) - { - item.TargetToSource(); - } - } - } - } - - - /// - /// 当要设置属性值的时候,返回值为true的时候将设置值 - /// - /// - /// - /// 返回值为true的时候将设置值 - protected virtual bool OnSetValue(string propertyName, ref object value) - { - return true; - } - ///// - ///// 清除对象设置的属性值,恢复默认值 - ///// - ///// - //public void ClearValue(string propertyName) - //{ - // if (values.ContainsKey(propertyName)) - // { - // var oldValue = GetValue(propertyName); - // values.Remove(propertyName); - // var newValue = GetValue(propertyName); - // if (!oldValue.Equal(newValue)) - // { - // OnPropertyChanged(propertyName, oldValue, newValue, GetPropertyMetadata(propertyName)); - // } - // } - //} - /// - /// 清除本地值 - /// - /// - public void ClearLocalValue(string propertyName) - { - EffectiveValue v; - if (TryGetValue(propertyName, out PropertyMetadataAttribute p, out v)) - { - var oldValue = GetValue(propertyName); - v.LocalValue = new EffectiveValueEntry(); - var newValue = GetValue(propertyName); - OnClearLocalValue(propertyName, v); - if ((oldValue != null && !oldValue.Equals(newValue)) || (oldValue == null && newValue != null)) - { - OnSetValue(propertyName, p, ValueForm.Property, newValue); - OnPropertyChanged(propertyName, oldValue, newValue, p); - } - } - } - - - internal virtual void OnClearLocalValue(string propertyName, EffectiveValue value) - { - - } - internal virtual void ClearAnimationValue(Storyboard Storyboard, string propertyName) - { - EffectiveValue value; - if (TryGetValue(propertyName, out PropertyMetadataAttribute p, out value)) - { - var oldValue = GetValue(propertyName); - var r = value.ClearAnimationValue(Storyboard); - if (r) - { - OnClearAnimationValue(propertyName, value); - //var pm = GetPropertyMetadata(propertyName); - var newValue = GetValue(propertyName); - if (!isDisposing && ((oldValue != null && !oldValue.Equals(newValue)) || (oldValue == null && newValue != null))) - { - OnSetValue(propertyName, p, ValueForm.Animation, newValue); - OnPropertyChanged(propertyName, oldValue, newValue, p); - } - } - } - } - - internal virtual void OnClearAnimationValue(string propertyName, EffectiveValue value) - { - - } - - internal virtual void ClearTriggerValue(Trigger Trigger, string propertyName) - { - EffectiveValue value; - if (TryGetValue(propertyName, out PropertyMetadataAttribute p, out value)) - { - var oldValue = GetValue(propertyName); - var r = value.ClearTriggerValue(Trigger); - if (r) - { - OnClearTriggerValue(propertyName, value); - var newValue = GetValue(propertyName); - if (!isDisposing && ((oldValue != null && !oldValue.Equals(newValue)) || (oldValue == null && newValue != null))) - { - OnSetValue(propertyName, p, ValueForm.Trigger, newValue); - OnPropertyChanged(propertyName, oldValue, newValue, p); - } - } - } - } - - internal virtual void OnClearTriggerValue(string propertyName, EffectiveValue value) - { - - } - - internal virtual void OnSetValue(string propertyName, PropertyMetadataAttribute property, ValueForm valueForm, object newValue) - { - - } - - internal void ClearStyleValue(Style style) - { - foreach (var item in objInfo) - { - EffectiveValue value = GetEffectiveValue(item.Value); - if (value.HasStyle(style)) - { - var oldValue = GetValue(item.Key); - var r = value.ClearStyleValue(style); - if (r) - { - OnClearStyleValue(item.Key, value); - var newValue = GetValue(item.Key); - if ((oldValue != null && !oldValue.Equals(newValue)) || (oldValue == null && newValue != null)) - { - OnSetValue(item.Key, item.Value, ValueForm.Style, newValue); - OnPropertyChanged(item.Key, oldValue, newValue, item.Value); - } - } - } - } - } - - internal virtual void OnClearStyleValue(string propertyName, EffectiveValue value) - { - - } - - internal void ClearStyleValues() - { - foreach (var item in objInfo) - { - //EffectiveValue value = values[item.Value.Id]; - EffectiveValue value = GetEffectiveValue(item.Value); - //if (TryGetValue(item.Key, out PropertyMetadataAttribute p, out value)) - if (value != null) - { - var oldValue = GetValue(item.Key); - var r = value.ClearStyleValues(); - if (r) - { - OnClearStyleValue(item.Key, value); - var newValue = GetValue(item.Key); - if (!isDisposing && ((oldValue != null && !oldValue.Equals(newValue)) || (oldValue == null && newValue != null))) - { - OnSetValue(item.Key, item.Value, ValueForm.Style, newValue); - OnPropertyChanged(item.Key, oldValue, newValue, item.Value); - } - } - } - } - } - - /// - /// 获取属性值 - /// - /// - /// - /// - public virtual T GetValue([CallerMemberName] string propertyName = null) - { - if (string.IsNullOrEmpty(propertyName)) - { - throw new Exception("propertyName不能为空"); - } - //Threading.Dispatcher.MainThread.VerifyAccess(); - EffectiveValue value; - if (TryGetValue(propertyName, out PropertyMetadataAttribute p, out value)) - { - object v; - if (value.GetValue(out v)) - { - return (T)v; - } - } - if (p == null) - { - throw new Exception("未找到该属性的元数据:" + propertyName); - } - return (T)OnGetDefaultValue(p); - } - /// - /// 内部使用,请勿调用 - /// - /// - /// - protected virtual object GetValue(in byte index) - { - var pa = propertyInfos[index]; - var value = GetEffectiveValue(pa); - object v; - if (value != null && value.GetValue(out v)) - { - return v; - } - return OnGetDefaultValue(pa); - } - - /// - /// 内部使用,请勿调用 - /// - /// - /// - protected virtual T GetValue(in byte index) - { - var pa = propertyInfos[index]; - var value = GetEffectiveValue(pa); - object v; - if (value != null && value.GetValue(out v)) - { - return (T)v; - } - return (T)OnGetDefaultValue(pa); - } - - public virtual PropertyMetadataAttribute GetPropertyMetadata(string propertyName) - { - PropertyMetadataAttribute p; - if (!objInfo.TryGetValue(propertyName, out p)) - { - return null; - } - return p; - } - - public virtual object GetValue([CallerMemberName] string propertyName = null) - { - return GetValue(propertyName); - } - /// - /// 获取默认值 - /// - /// - /// - protected virtual object OnGetDefaultValue(PropertyMetadataAttribute property) - { - return property.DefaultValue; - } - /// - /// 是否已经设置了本地值 - /// - /// - /// - public bool HasLocalValue(string propertyName) - { - EffectiveValue v; - if (TryGetValue(propertyName, out PropertyMetadataAttribute p, out v)) - { - if (v.LocalValue.HasValue) - { - return true; - } - } - return false; - } - - public bool HasLocalOrStyleValue(string propertyName, out PropertyMetadataAttribute attribute) - { - EffectiveValue v; - if (TryGetValue(propertyName, out attribute, out v)) - { - if (v.LocalValue.HasValue || v.HasStyleValue()) - { - return true; - } - } - return false; - } - - /// - /// 触发事件 - /// - /// EventArgs类型要和事件的数据类型对应 - /// - public void RaiseEvent(in TEventArgs eventArgs, string eventName) - { - //if (eventArgs is RoutedEventArgs routed) - //{ - // routed.Sender = this; - //} - OnRaiseEvent(eventArgs, eventName); - - if (observers != null && eventArgs is EventArgs args) - { - EventObserver eventObserver = new EventObserver(eventName, args, this); - foreach (var observer in observers) - { - observer.OnNext(eventObserver); - } - } - - var handler = Events[eventName]; - if (handler != null) - { - handler.Invoke(this, eventArgs); - } - if (commands != null) - { - List list; - if (commands.commands.TryGetValue(eventName, out list)) - { - foreach (var item in list) - { - if (item.Action == null) - { - var objs = new List(); - object v = null; - if (item.Target != null) - { - v = item.Target.Target; - objs.Add(v); - } - //else if (item.Relation != null && this is UIElement) - //{ - // objs.AddRange(item.Relation.Query(this as UIElement)); - //} - else - { - v = CommandContext; - if (v != null) - { - objs.Add(v); - } - } - foreach (var obj in objs) - { - if (obj == null) - { - continue; - } - object[] ps = new object[item.Params == null ? 0 : item.Params.Length]; - if (item.Params != null && item.Params.Length > 0) - { - //ps = item.Params; - item.Params.CopyTo(ps, 0); - for (int i = 0; i < ps.Length; i++) - { - var p = ps[i]; - if (p is CommandParameter) - { - if ((CommandParameter)p == CommandParameter.EventArgs) - { - ps[i] = eventArgs; - } - else if ((CommandParameter)p == CommandParameter.EventSender) - { - ps[i] = this; - } - } - } - } - //v.GetType().GetMethod(item.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).FastInvoke(v, ps); - - //var m = obj.GetType().GetMethod(item.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - //if (m == null) - //{ - // throw new Exception("未找到该方法 " + item.MethodName); - //} - //m.FastInvoke(obj, ps); - obj.Invoke(item.MethodName, ps); - } - } - else - { - item.Action(this, eventArgs); - } - } - } - } - } - - protected virtual void OnRaiseEvent(in TEventArgs eventArgs, string eventName) - { - - } - - PropertyChangedEventHandler propertyChangedEventHandler; - /// - /// 当有属性更改之后发生 - /// - event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged - { - add - { - //Events.AddHandler("INotifyPropertyChanged", value); - propertyChangedEventHandler = (PropertyChangedEventHandler)Delegate.Combine(propertyChangedEventHandler, value); - //if (propertyChangedEventHandler == null) - //{ - // propertyChangedEventHandler = new WeakEvent(); - //} - //propertyChangedEventHandler.AddHandler(value); - } - remove - { - //Events.RemoveHandler("INotifyPropertyChanged", value); - propertyChangedEventHandler = (PropertyChangedEventHandler)Delegate.Remove(propertyChangedEventHandler, value); - //if (propertyChangedEventHandler != null) - //{ - // propertyChangedEventHandler.RemoveHandler(value); - //} - } - } - - public event EventHandler PropertyChanged - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - ///// - ///// 当有属性更改的时候发生 - ///// - //public event PropertyChangingEventHandler PropertyChanging - //{ - // add { AddHandler(value); } - // remove { RemoveHandler(value); } - //} - - WeakEventHandlerList events; - /// - /// 事件列表,用于优化事件订阅内存 - /// - [NotCpfProperty] - protected WeakEventHandlerList Events - { - get - { - if (events == null) - { - events = new WeakEventHandlerList(); - } - return events; - } - } - /// - /// 为指定的事件添加事件处理程序,并将该处理程序添加到当前元素的处理程序集合中。 - /// - /// - /// - public void AddHandler(Delegate handler, [CallerMemberName] string eventName = null) - { - Events.AddHandler(eventName, handler); - } - /// - /// 从此元素中删除指定的路由事件处理程序。 - /// - /// - /// - public void RemoveHandler(Delegate handler, [CallerMemberName] string eventName = null) - { - Events.RemoveHandler(eventName, handler); - } - - - ///// - ///// 移除处理命令 - ///// - ///// 触发的事件名 - ///// 方法名 - ///// 属性名 - //public void RemoveCommand(string eventName, string methodName, object obj) - //{ - // if (commands != null) - // { - // List list; - // if (commands.TryGetValue(eventName, out list)) - // { - // var f = list.FirstOrDefault(a => a.MethodName == methodName && a.PropertyName == propertyName); - // if (f != null) - // { - // list.Remove(f); - // } - // } - // } - //} - /// - /// 是否包含这个依赖属性 - /// - /// - /// - public virtual bool HasProperty(string propertyName) - { - return objInfo.ContainsKey(propertyName); - } - - #region IDisposable Support - private bool disposedValue = false; - bool isDisposing; - - [NotCpfProperty] - public bool IsDisposing - { - get { return isDisposing; } - } - - [NotCpfProperty] - public bool IsDisposed - { - get { return disposedValue; } - } - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // TODO: 释放托管状态(托管对象)。 - //values.Clear(); - if (bindings != null) - { - foreach (var item in bindings.binds.Select(a => a.Value).ToArray()) - { - foreach (var i in item.ToArray()) - { - i.UnBind(); - } - } - } - //foreach (var item in values) - //{ - // if (item != null) - // { - // item.ClearTriggerValues(this); - // } - //} - for (int i = 0; i < valueList.Count; i++) - { - var item = valueList[i]; - if (item != null) - { - item.ClearTriggerValues(this); - } - } - //values = null; - } - // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。 - // TODO: 将大型字段设置为 null。 - disposedValue = true; - } - } - - // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。 - ~CpfObject() - { - // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。 - Dispose(false); - } - - // 添加此代码以正确实现可处置模式。 - public void Dispose() - { - isDisposing = true; - // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。 - Dispose(true); - if (events != null) - { - events.Dispose(); events = null; - } - propertyChangedEventHandler = null; - // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。 - //valueIndexs.Dispose(); - GC.SuppressFinalize(this); - } - - #endregion - - /// - /// 不为null而且没有释放,则返回true - /// - /// - public static implicit operator bool(CpfObject CPFObject) - { - return CPFObject != null && !CPFObject.IsDisposed; - } - /// - /// 克隆依赖属性和绑定 - /// - /// - public virtual object Clone() - { - var obj = Type.GetConstructor(new Type[] { }).FastInvoke() as CpfObject; - CopyTo(obj, true); - return obj; - } - /// - /// 将依赖属性本地值和绑定拷贝到另外个对象 - /// - /// - /// 是否覆盖已经存在的本地值 - public virtual void CopyTo(CpfObject obj, bool cover = false) - { - //foreach (var item in values) - //{ - // if (!obj.values.TryGetValue(item.Key, out EffectiveValue value)) - // { - // obj.values.Add(item.Key, item.Value); - // } - // else - // { - // if (cover || !value.LocalValue.HasValue) - // { - // value.LocalValue = item.Value.LocalValue; - // } - // } - //} - if (obj.Type != Type) - { - throw new Exception("目标类型不一致"); - } - if (cover) - { - //obj.values = values.ToArray(); - obj.valueIndexs = valueIndexs.ToArray(); - obj.valueList = valueList.Clone(); - } - else - { - //for (int i = 0; i < values.Length; i++) - //{ - // if (obj.values[i] == null || !obj.values[i].LocalValue.HasValue) - // { - // obj.values[i] = values[i]; - // } - //} - for (int i = 0; i < obj.valueIndexs.Length; i++) - { - var ti = obj.valueIndexs[(byte)i] - 1; - var si = valueIndexs[(byte)i] - 1; - var tv = obj.valueList[ti]; - var sv = valueList[si]; - if ((si > -1 && sv != null) && (ti < 0 || tv == null || !tv.LocalValue.HasValue)) - { - if (ti < 0) - { - obj.valueList.Add(new EffectiveValue { LocalValue = sv.LocalValue }); - obj.valueIndexs[(byte)i] = obj.valueList.Count; - } - else if (tv != null) - { - tv.LocalValue = sv.LocalValue; - } - else - { - obj.valueList[ti] = new EffectiveValue { LocalValue = sv.LocalValue }; - } - } - } - } - - if (bindings != null) - { - //obj.Bindings.binds.Clear(); - foreach (var item in bindings.binds) - { - List bindings = new List(); - foreach (var b in item.Value) - { - bindings.Add(new Binding { BindingMode = b.BindingMode, Convert = b.Convert, ConvertBack = b.ConvertBack, IsDataContext = b.IsDataContext, Owner = obj, SourceElementLayer = b.SourceElementLayer, SourcePropertyName = b.SourcePropertyName, TargetPropertyName = b.TargetPropertyName, Source = b.SourceElementLayer.HasValue ? null : b.Source }); - } - obj.Bindings.binds.Add(item.Key, bindings); - } - } - - if (commands != null) - { - //obj.Commands.commands.Clear(); - foreach (var item in commands.commands) - { - List commands = new List(); - foreach (var c in item.Value) - { - commands.Add(new Command - { - MethodName = c.MethodName, - Params = c.Params, - //Relation = c.Relation, - Target = c.Target, - Action = c.Action - }); - } - obj.Commands.commands.Add(item.Key, commands); - } - } - - if (attachedValues != null) - { - obj.attachedValues = new HybridDictionary(); - foreach (var item in attachedValues) - { - obj.attachedValues.Add(item); - } - } - - } - - public virtual string GetCreationCode() - { - var ps = GetHasLocalValueProperties().Select(a => $"{a.Item1} = {a.Item2.GetCreationCode()},").ToArray(); - var c = $"new {type.Name}{{ {string.Join(" ", ps)} }}"; - return c; - } - - - List>> observers; - /// - /// 订阅通知 - /// - /// - /// - public IDisposable Subscribe(IObserver> observer) - { - if (observers == null) - { - observers = new List>>(); - } - observers.Add(observer); - return new Unsubscribe(this.observers, observer); - } - /// - /// 取消订阅类 - /// - class Unsubscribe : IDisposable - { - List>> observers; - IObserver> observer; - public Unsubscribe(List>> observers - , IObserver> observer) - { - this.observer = observer; - this.observers = observers; - } - - public void Dispose() - { - if (this.observers != null) - { - this.observers.Remove(observer); - } - } - } - } - - //public class PInfo - //{ - - // public PropertyInfo PropertyInfo { get; internal set; } - - // public PropertyMetadataAttribute PropertyMetadata { get; internal set; } - //} - /// - /// 不使用属性管理 - /// - [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] - public class NotCpfProperty : Attribute - { - - } - - public delegate void EventHandlerRef(object sender, in TEventArgs e); - - /// - /// 属性元数据,设置默认值,必须显示转换 - /// - [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] - public class PropertyMetadataAttribute : Attribute - { - internal PropertyMetadataAttribute() { } - /// - /// 设置默认值,必须显示转换 - /// - /// - public PropertyMetadataAttribute(object defaultValue) - { - DefaultValue = defaultValue; - } - - /// - /// 设置默认值,通过设定的类型和字符串转换 - /// - /// - /// - public PropertyMetadataAttribute(Type type, string value) - { - // load an otherwise normal class. - try - { - this.DefaultValue = type.Parse(value); - } - catch - { - throw new InvalidCastException("Default value attribute of type " + type.FullName + " threw converting from the string '" + value + "'."); - } - } - /// - /// 默认值 - /// - public object DefaultValue { get; internal set; } - /// - /// 属性值类型 - /// - public Type PropertyType { get; internal set; } - /// - /// 属性名 - /// - public string PropertyName { get; internal set; } - - internal byte Id; - /// - /// 属性通知 - /// - internal List actions; - } - /// - /// UI属性元数据,设置默认值,必须显示转换 - /// - public class UIPropertyMetadataAttribute : PropertyMetadataAttribute - { - /// - /// UI属性元数据 - /// - /// 默认值 - /// 属性值是否继承父级容器 - public UIPropertyMetadataAttribute(object defaultValue, bool inherits) : base(defaultValue) - { - //Inherits = inherits; - UIPropertyMetadataOptions = inherits ? UIPropertyOptions.Inherits : UIPropertyOptions.None; - } - /// - /// UI属性元数据 - /// - /// - /// - /// - public UIPropertyMetadataAttribute(Type type, string value, bool inherits) : base(type, value) - { - UIPropertyMetadataOptions = inherits ? UIPropertyOptions.Inherits : UIPropertyOptions.None; - //Inherits = inherits; - } - /// - /// UI属性元数据 - /// - /// 默认值 - /// 属性变化之后的操作,支持位运算组合 - public UIPropertyMetadataAttribute(object defaultValue, UIPropertyOptions options) : base(defaultValue) - { - UIPropertyMetadataOptions = options; - //Inherits = inherits; - //NeedInvalidate = needInvalidate; - //NeedLayout = needLayout; - } - ///// - ///// UI属性元数据 - ///// - ///// 属性值类型 - ///// 默认值 - ///// 属性值是否继承父级容器 - ///// 属性变化是否需要重新布局 - ///// 属性变化是否需要重新绘制 - //public UIPropertyMetadataAttribute(Type type, string value, bool inherits, bool needLayout, bool needInvalidate) : base(type, value) - //{ - // //Inherits = inherits; - // //NeedInvalidate = needInvalidate; - // //NeedLayout = needLayout; - //} - /// - /// UI属性元数据 - /// - /// 属性值类型 - /// 默认值 - /// 属性变化之后的操作,支持位运算组合 - public UIPropertyMetadataAttribute(Type type, string value, UIPropertyOptions options) : base(type, value) - { - UIPropertyMetadataOptions = options; - } - - private static bool IsFlagSet(UIPropertyOptions flag, UIPropertyOptions flags) - { - return (flags & flag) != 0; - } - /// - /// 属性变化之后的操作 - /// - public UIPropertyOptions UIPropertyMetadataOptions { get; } - - /// - /// 属性值是否继承父级容器 - /// - public bool Inherits { get { return IsFlagSet(UIPropertyOptions.Inherits, UIPropertyMetadataOptions); } } - /// - /// 属性变化是否需要重新布局 - /// - public bool AffectsArrange { get { return IsFlagSet(UIPropertyOptions.AffectsArrange, UIPropertyMetadataOptions); } } - /// - /// 重新计算元素尺寸 - /// - public bool AffectsMeasure { get { return IsFlagSet(UIPropertyOptions.AffectsMeasure, UIPropertyMetadataOptions); } } - /// - /// 属性变化是否需要重新绘制 - /// - public bool AffectsRender { get { return IsFlagSet(UIPropertyOptions.AffectsRender, UIPropertyMetadataOptions); } } - - } - - - internal class EffectiveValue - { - //public PropertyMetadataAttribute PropertyMetadata; - public _List AnimationValue; - public EffectiveValueEntry LocalValue; - public _List TriggerValue; - public _List styleValues; - //public EffectiveValueEntry TemplateValue; - public void SetStyleValue(Style style, object value) - { - if (styleValues == null) - { - styleValues = new _List(); - } - else - { - if (styleValues.Any(a => a.Style == style)) - { - return; - } - } - styleValues.Add(new StyleValue { Style = style, Value = value }); - } - - public void SetTriggerValue(Trigger Trigger, object value) - { - if (TriggerValue == null) - { - TriggerValue = new _List(); - } - TriggerValue.Add(new TriggerValue { Trigger = Trigger, Value = value }); - //if (StyleValue.Count > 1) - //{ - // //StyleValue.Sort(new StyleValueSort()); - // SortStyleValue(); - //} - } - - ///// - ///// 根据Priority属性排序 - ///// - //internal void SortStyleValue() - //{//选择排序 - // int min; - // for (int i = 0; i < StyleValue.Count; i++) - // { - // min = i; - // for (int j = i + 1; j < StyleValue.Count; j++) - // { - // if (StyleValue[j].Priority - StyleValue[min].Priority < 0) - // { - // min = j; - // } - // } - // var temp = StyleValue[i]; - // StyleValue[i] = StyleValue[min]; - // StyleValue[min] = temp; - // } - //} - - public bool ClearStyleValue(Style style) - { - if (styleValues != null) - { - var v = styleValues.FirstOrDefault(a => a.Style == style); - if (v != null) - { - styleValues.Remove(v); - if (styleValues.Count == 0) - { - styleValues = null; - } - return true; - } - } - return false; - } - - public bool ClearStyleValues() - { - if (styleValues != null && styleValues.Count > 0) - { - styleValues = null; - return true; - } - return false; - } - - public bool ClearTriggerValue(Trigger Trigger) - { - if (TriggerValue != null) - { - //var v = TriggerValue.ListFirstOrDefault(a => a.Trigger == Trigger); - //if (v != null) - //{ - // TriggerValue.Remove(v); - // return true; - //} - bool r = false; - for (int i = TriggerValue.Count - 1; i >= 0; i--) - { - if (TriggerValue[i].Trigger == Trigger) - { - TriggerValue.RemoveAt(i); - r = true; - } - } - return r; - } - return false; - } - - public void ClearTriggerValues(CpfObject owner) - { - if (TriggerValue != null) - { - for (int i = TriggerValue.Count - 1; i >= 0; i--) - { - var t = TriggerValue[i].Trigger; - if (t != null) - { - if (t.SetPropertys != null) - { - t.SetPropertys.Remove(owner); - } - } - } - TriggerValue.Clear(); - } - } - - public void SetAnimationValue(Storyboard Storyboard, object Value) - { - if (AnimationValue == null) - { - AnimationValue = new _List(); - } - var v = AnimationValue.FirstOrDefault(a => a.Storyboard == Storyboard); - if (v != null) - { - v.Value = Value; - } - else - { - AnimationValue.Add(new AnimationValue { Storyboard = Storyboard, Value = Value }); - } - } - - public bool ClearAnimationValue(Storyboard Storyboard) - { - if (AnimationValue != null) - { - var v = AnimationValue.FirstOrDefault(a => a.Storyboard == Storyboard); - if (v != null) - { - AnimationValue.Remove(v); - return true; - } - } - return false; - } - - public bool HasStyleValue() - { - if (AnimationValue != null && AnimationValue.Count > 0) - { - return true; - } - if (TriggerValue != null && TriggerValue.Count > 0) - { - return true; - } - if (styleValues != null && styleValues.Count > 0) - { - return true; - } - return false; - } - - public bool HasStyle(Style style) - { - if (styleValues != null) - { - return styleValues.Any(a => a.Style == style); - } - return false; - } - - public bool GetLocalValue(out object value) - { - if (LocalValue.HasValue) - { - value = LocalValue.Value; - return true; - } - value = null; - return false; - } - - public bool GetValue(out object value) - { - if (AnimationValue != null && AnimationValue.Count > 0) - { - value = AnimationValue[AnimationValue.Count - 1].Value; - return true; - } - if (TriggerValue != null && TriggerValue.Count > 0) - { - value = TriggerValue[TriggerValue.Count - 1].Value; - return true; - } - if (styleValues != null && styleValues.Count > 0) - { - value = styleValues[styleValues.Count - 1].Value; - return true; - } - if (LocalValue.HasValue) - { - value = LocalValue.Value; - return true; - } - //if (TemplateValue.HasValue) - //{ - // value = TemplateValue.Value; - // return true; - //} - value = null; - return false; - } - } - class AnimationValue - { - public Storyboard Storyboard; - public object Value; - } - class TriggerValue - { - public Trigger Trigger; - - //public int Priority; - - public object Value; - } - - class StyleValue - { - public Style Style; - - //public int Priority; - - public object Value; - } - - internal struct EffectiveValueEntry - { - //internal int PropertyIndex { get; set; } - internal bool HasValue; - - internal object Value; - } - - //class StyleValueSort : IComparer - //{ - // public int Compare(StyleValue x, StyleValue y) - // { - // return x.Priority - y.Priority; - // } - //} - - public class CPFPropertyChangedEventArgs : EventArgs - { - public string PropertyName { get; set; } - - public object OldValue { get; set; } - - public object NewValue { get; set; } - - public PropertyMetadataAttribute PropertyMetadata { get; set; } - } - - /// - /// 属性元数据重写 - /// - public class OverrideMetadata - { - internal Dictionary list = new Dictionary(); - /// - /// 属性元数据重写 - /// - /// - /// - public void Override(string propertyName, PropertyMetadataAttribute propertyMetadata) - { - if (list.ContainsKey(propertyName)) - { - list.Remove(propertyName); - } - list.Add(propertyName, propertyMetadata); - } - } - - public class ComputeProtertyInfo - { - public PropertyInfo Property { get; set; } - - public string[] NoticeProperties { get; set; } - - public int[] Tokens { get; set; } - } - - /// - /// 属性变化之后的操作 - /// - [Flags] - public enum UIPropertyOptions : byte - { - /// No flags - None = 0x000, - - /// This property affects measurement - AffectsMeasure = 0x001, - - /// This property affects arragement - AffectsArrange = 0x002, - - ///// This property affects parent's measurement - //AffectsParentMeasure = 0x004, - - ///// This property affects parent's arrangement - //AffectsParentArrange = 0x008, - - /// This property affects rendering - AffectsRender = 0x010, - - /// This property inherits to children - Inherits = 0x020, - - ///// - ///// This property causes inheritance and resource lookup to override values - ///// of InheritanceBehavior that may be set on any FE in the path of lookup - ///// - //OverridesInheritanceBehavior = 0x040, - - ///// This property does not support data binding - //NotDataBindable = 0x080, - - ///// Data bindings on this property default to two-way - //BindsTwoWayByDefault = 0x100, - - ///// This property should be saved/restored when journaling/navigating by URI - //Journal = 0x400, - - ///// - ///// This property's subproperties do not affect rendering. - ///// For instance, a property X may have a subproperty Y. - ///// Changing X.Y does not require rendering to be updated. - ///// - //SubPropertiesDoNotAffectRender = 0x800, - } - - /// - /// 获取或者设置附加属性值 - /// - /// - /// - /// - /// - public delegate Value Attached(CpfObject obj, OptionalParameter value = default); - /// - /// CpfObject obj, string propertyName, object defaultValue, object oldValue, ref object newValue - /// - /// - /// - /// - /// - /// - public delegate void AttachedPropertyChanged(CpfObject obj, string propertyName, object defaultValue, object oldValue, ref object newValue); - /// - /// 属性通知回调 - /// - /// - /// - /// - /// - delegate void PropertyChangedCallback(CpfObject obj, object newValue, object oldValue, PropertyMetadataAttribute attribute); - ///// - ///// 属性通知注册器 - ///// - //public class PropertyChangedRegister - //{ - // /// - // /// 注册属性通知 - // /// - // /// - // /// CpfObject obj, string propertyName, object newValue, object oldValue, PropertyMetadataAttribute attribute - // public void Register(string propertyName, PropertyChangedCallback propertyChangedCallback) - // { - // if (!propertyChangedCallback.Method.IsStatic) - // { - // throw new Exception("注册的通知回调必须是静态函数"); - // } - // if (callbacks == null) - // { - // callbacks = new List<(string, PropertyChangedCallback)>(); - // } - // callbacks.Add((propertyName, propertyChangedCallback)); - // } - - // internal List> callbacks; - //} - - /// - /// 定义该方法为属性通知方法,支持绑定多个,方法类型 void Method(object newValue, object oldValue, CPF.PropertyMetadataAttribute attribute) - /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] - public class PropertyChangedAttribute : Attribute - { - /// - /// 定义该方法为属性通知方法,方法类型 void Method(object newValue, object oldValue, CPF.PropertyMetadataAttribute attribute) - /// - /// 属性名 - public PropertyChangedAttribute(string propertyName) - { - PropertyName = propertyName; - if (string.IsNullOrWhiteSpace(propertyName)) - { - throw new Exception("propertyName不能为空"); - } - } - /// - /// 通知的属性名 - /// - public string PropertyName { get; set; } - } - [DebuggerDisplay("Count = {Count}")] - [Serializable] - class _List - { - public _List() - { - _items = _emptyArray; - } - - private T[] _items; - private byte _size; - private byte maxSize = 255; - public byte MaxSize - { - get { return maxSize; } - set { maxSize = value; } - } - - public byte Count - { - get { return _size; } - } - - public T this[int index] - { - get - { - // Following trick can reduce the range check by one - if ((uint)index >= _size) - { - throw new Exception("超出范围" + index); - } - return _items[index]; - } - - set - { - if ((uint)index >= _size) - { - throw new Exception("超出范围" + index); - } - _items[index] = value; - } - } - - public void Add(T item) - { - if (_size == _items.Length) - { - EnsureCapacity(_size + 1); - } - _items[_size] = item; - _size++; - } - - public void Clear() - { - if (_size > 0) - { - Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references. - _size = 0; - } - } - public int IndexOf(T item) - { - return Array.IndexOf(_items, item, 0, _size); - } - public bool Remove(T item) - { - int index = IndexOf(item); - if (index >= 0) - { - RemoveAt(index); - return true; - } - - return false; - } - - public void RemoveAt(int index) - { - if ((uint)index >= _size) - { - throw new Exception("超出范围" + index); - } - _size--; - if (index < _size) - { - Array.Copy(_items, index + 1, _items, index, _size - index); - } - _items[_size] = default(T); - } - static readonly T[] _emptyArray = new T[0]; - private void EnsureCapacity(int min) - { - if (_items.Length < min) - { - int value = _items.Length == 0 ? 1 : _items.Length + 2; - if (min <= maxSize && value > maxSize) - { - value = maxSize; - } - else if (min > maxSize) - { - throw new Exception("超过容量" + maxSize); - } - if (value != _items.Length) - { - if (value > 0) - { - T[] newItems = new T[value]; - if (_size > 0) - { - Array.Copy(_items, 0, newItems, 0, _size); - } - _items = newItems; - } - else - { - _items = _emptyArray; - } - } - } - } - - public T FirstOrDefault(Func func) - { - for (int i = 0; i < _size; i++) - { - if (func(_items[i])) - { - return _items[i]; - } - } - return default; - } - - public bool Any(Func func) - { - for (int i = 0; i < _size; i++) - { - if (func(_items[i])) - { - return true; - } - } - return false; - } - public _List Clone() - { - var list = new _List(); - list._size = _size; - list.maxSize = maxSize; - list._items = new T[_size]; - if (_size > 0) - { - Array.Copy(_items, 0, list._items, 0, _size); - } - return list; - } - - public void Sort(IComparer comparison) - { - Array.Sort(_items, 0, _size, comparison); - } - } - - //public unsafe class ByteArray : IDisposable, IEnumerable - //{ - // public byte Length; - // IntPtr intPtr; - - // public byte this[in byte index] - // { - // get - // { - // if (index > Length) - // { - // throw new IndexOutOfRangeException("ByteArray访问超索引"); - // } - // if (intPtr == IntPtr.Zero) - // { - // return 0; - // } - // return ((byte*)intPtr)[index]; - // } - // set - // { - // if (index > Length) - // { - // throw new IndexOutOfRangeException("ByteArray访问超索引"); - // } - // ((byte*)intPtr)[index] = value; - // } - // } - - // public ByteArray(byte len) - // { - // Length = len; - // intPtr = Marshal.AllocHGlobal(len); - // var s = (byte*)intPtr; - // for (int i = 0; i < Length; i++) - // { - // s[i] = 0; - // } - // } - - // ByteArray() - // { - - // } - - // public ByteArray Clone() - // { - // var by = new ByteArray(); - // by.Length = Length; - // by.intPtr = Marshal.AllocHGlobal(Length); - // var t = (byte*)by.intPtr; - // var s = (byte*)intPtr; - // for (int i = 0; i < Length; i++) - // { - // t[i] = s[i]; - // } - // return by; - // } - - // protected virtual void Dispose(bool disposing) - // { - // if (intPtr != IntPtr.Zero) - // { - // Marshal.FreeHGlobal((IntPtr)intPtr); - // intPtr = IntPtr.Zero; - // } - // } - - // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器 - // ~ByteArray() - // { - // // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 - // Dispose(disposing: false); - // } - - // public void Dispose() - // { - // // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 - // Dispose(disposing: true); - // GC.SuppressFinalize(this); - // } - - // public IEnumerator GetEnumerator() - // { - // return new ByteArrayIEnumerator(this); - // } - //} - - //class ByteArrayIEnumerator : IEnumerator - //{ - // ByteArray byteArray; - // short position = -1; - // public ByteArrayIEnumerator(ByteArray byteArray) - // { - // this.byteArray = byteArray; - // } - // public object Current - // { - // get - // { - // try - // { - // return byteArray[(byte)position]; - // } - // catch (IndexOutOfRangeException) - // { - // throw new InvalidOperationException(); - // } - // } - // } - - // public bool MoveNext() - // { - // position++; - // return (position < byteArray.Length); - // } - - // public void Reset() - // { - // position = -1; - // } - //} - -} diff --git a/CPF/UIElement - 副本.cs b/CPF/UIElement - 副本.cs deleted file mode 100644 index 3b14114..0000000 --- a/CPF/UIElement - 副本.cs +++ /dev/null @@ -1,4046 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using CPF; -using CPF.Input; -using CPF.Styling; -using CPF.Shapes; -using System.Linq; -using System.ComponentModel; -using System.ComponentModel.Design; -using System.ComponentModel.Design.Serialization; -using System.Runtime.CompilerServices; -using CPF.Controls; -using CPF.Drawing; -using System.Runtime.InteropServices; -using System.Collections; -using System.Diagnostics; - -namespace CPF -{ - /// - /// 提供UI相关的特性,图像,鼠标事件,触摸事件,布局,拖拽事件 - /// - //[ContentProperty("Children")] - //[Designer(typeof(Design.DocumentDesigner), typeof(IRootDesigner))] - //[Designer(typeof(Design.DocumentDesigner), typeof(IDesigner))] - [DesignerCategory("Component")] - //[DesignerSerializer(typeof(),typeof(System.ComponentModel.Design.Serialization.CodeDomSerializer))] - [ToolboxItem(false)] - public class UIElement : Visual, IComponent//, IEnumerable//, INamed//, IInputElement - { - //internal bool needSortZIndex = false; - //List visibleElements; - internal UIElement mouseOverChild = null; - internal UIElement dragOverChild = null; - Size desiredSize; - Rect previousRenderRect; - //Size previousDesiredSize; - //bool isMeasureValid = true; - internal Rect? _previousArrange; - internal Size? _previousMeasure; - Rect contentBounds; - HybridDictionary> notifyList; - Effects.Effect effect; - static Popup tooltip; - static Threading.DispatcherTimer timer; - static Popup ToolTipHost - { - get - { - if (tooltip == null) - { - tooltip = new Popup() { Name = "tooltip", CanActivate = false, Background = Color.Transparent }; - } - return tooltip; - } - } - - static void ShowTip(View root, UIElement toolTipElement) - { - if (timer == null) - { - timer = new Threading.DispatcherTimer(); - timer.Interval = TimeSpan.FromSeconds(.3); - timer.Tick += Timer_Tick; - } - UIElement.toolTipRoot = root; - ToolTipUIElement = toolTipElement; - timer.Start(); - } - static View toolTipRoot; - static UIElement toolTipUIElement; - static UIElement ToolTipUIElement - { - get { return toolTipUIElement; } - set - { - if (toolTipUIElement != value) - { - if (toolTipUIElement != null) - { - ToolTipHost.Children.Remove(toolTipUIElement); - if (tooltip.Visibility == Visibility.Visible) - { - tooltip.Visibility = Visibility.Collapsed; - } - } - } - toolTipUIElement = value; - } - } - private static void Timer_Tick(object sender, EventArgs e) - { - timer.Stop(); - if (toolTipRoot == null || !toolTipUIElement) - { - return; - } - var p = MouseDevice.Location; - ToolTipHost.MarginLeft = p.X / toolTipRoot.LayoutScaling + 10; - ToolTipHost.MarginTop = p.Y / toolTipRoot.LayoutScaling + 10; - ToolTipHost.LoadStyle(toolTipRoot); - ToolTipHost.Children.Add(toolTipUIElement); - ToolTipHost.Visibility = Visibility.Visible; - UIElement.toolTipRoot = null; - //toolTipUIElement = null; - } - - internal Classes classes; - internal long lastMouseDownTime; - internal void RaiseDeviceEvent(EventArgs e, EventType eventName) - { - if (Root == null) - { - return; - } - if (eventName == EventType.MouseMove) - { - OnMouseMove((MouseEventArgs)e); - } - else if (eventName == EventType.PreviewMouseDown) - { - OnPreviewMouseDown((MouseButtonEventArgs)e); - } - else if (eventName == EventType.PreviewMouseUp) - { - OnPreviewMouseUp((MouseButtonEventArgs)e); - } - else if (eventName == EventType.MouseDown) - { - OnMouseDown((MouseButtonEventArgs)e); - if (lastMouseDownTime != 0) - { - var time = DateTime.FromBinary(lastMouseDownTime); - var now = DateTime.FromBinary(((MouseButtonEventArgs)e).timestamp); - if (Platform.Application.GetRuntimePlatform().DoubleClickTime > (now - time)) - { - OnDoubleClick((RoutedEventArgs)e); - return; - } - } - lastMouseDownTime = ((MouseButtonEventArgs)e).timestamp; - } - else if (eventName == EventType.MouseUp) - { - OnMouseUp((MouseButtonEventArgs)e); - } - else if (eventName == EventType.MouseEnter) - { - OnMouseEnter((MouseEventArgs)e); - } - else if (eventName == EventType.MouseLeave) - { - OnMouseLeave((MouseEventArgs)e); - } - else if (eventName == EventType.MouseWheel) - { - OnMouseWheel((MouseWheelEventArgs)e); - } - else if (eventName == EventType.KeyDown) - { - OnKeyDown((KeyEventArgs)e); - } - else if (eventName == EventType.KeyUp) - { - OnKeyUp((KeyEventArgs)e); - } - else if (eventName == EventType.TextInput) - { - OnTextInput((TextInputEventArgs)e); - //} - //else if (eventName == EventType.DoubleClick) - //{ - // if (lastMouseDownTime != 0) - // { - // var time = DateTime.FromBinary(lastMouseDownTime); - // var now = DateTime.FromBinary(((MouseButtonEventArgs)e).timestamp); - // if (Platform.Application.GetRuntimePlatform().DoubleClickTime > (now - time)) - // { - // OnDoubleClick((RoutedEventArgs)e); - // } - // } - } - else if (eventName == EventType.DragOver) - { - OnDragOver((DragEventArgs)e); - } - else if (eventName == EventType.DragEnter) - { - OnDragEnter((DragEventArgs)e); - } - else if (eventName == EventType.DragLeave) - { - OnDragLeave(e); - } - else if (eventName == EventType.Drop) - { - OnDrop((DragEventArgs)e); - } - } - public UIElement() - { - loadStyle = true; - IsMeasureValid = true; - if (inheritsPropertyName != null) - { - inheritsValues = new Dictionary(); - } - } - Dictionary inheritsValues; - - List presenters; - /// - /// 被标记了的元素 - /// - [NotCpfProperty, Browsable(false)] - public IEnumerable Presenters - { - get { return presenters; } - } - - UIElement presenterFor; - /// - /// 用作模板中的特殊元素的标记 - /// - [NotCpfProperty] - [Browsable(false)] - public UIElement PresenterFor - { - get { return presenterFor; } - set - { - if (presenterFor != value) - { - if (value != null) - { - if (value.presenters == null) - { - value.presenters = new List(); - } - value.presenters.Add(this); - } - if (presenterFor != null && presenterFor.presenters != null) - { - presenterFor.presenters.Remove(this); - } - presenterFor = value; - } - - } - } - /// - /// 查找标记了的特殊元素 - /// - /// - public IEnumerable FindPresenter() where T : UIElement - { - //return Find().Where(a => a.PresenterFor == this); - if (presenters == null) - { - yield break; - } - foreach (var item in presenters) - { - if (item is T t) - { - yield return t; - } - } - } - /// - /// 查找标记了的特殊元素,绑定的时候使用 - /// - /// - /// - /// - public Func FindPresenter(Func func) where T : UIElement - { - Func func1 = a => - { - return FindPresenter().FirstOrDefault(func); - }; - return func1; - } - - /// - /// 查找标记了的特殊元素 - /// - /// - public IEnumerable FindPresenter() - { - return FindPresenter(); - } - /// - /// 通过Name查找标记了的特殊元素 - /// - /// - /// - /// - public T FindPresenterByName(string name) where T : UIElement - { - return FindPresenter().FirstOrDefault(a => a.Name == name); - } - /// - /// 通过Name查找标记了的特殊元素。绑定的时候用 - /// - /// - /// - public Func FindPresenterByName(string name) - { - Func func1 = b => - { - return FindPresenter().FirstOrDefault(a => a.Name == name); - }; - return func1; - } - - ///// - ///// 添加子元素 Children.Add(element); - ///// - ///// - //public void Add(UIElement element) - //{ - // Children.Add(element); - //} - - /// - /// 位图特效 - /// - [Description("位图特效")] - [UIPropertyMetadata(null, UIPropertyOptions.AffectsRender)] - [Browsable(false)] - public Effects.Effect Effect - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 获取或设置在用户界面 (UI) 中为此元素显示的工具提示对象 - /// - [Description("获取或设置在用户界面 (UI) 中为此元素显示的工具提示对象"), TypeConverter(typeof(StringConverter))] - public object ToolTip - { - get { return GetValue(); } - set { SetValue(value); } - } - UIElement toolTipElement; - //public UIElement(IViewImpl host) : this() - //{ - // this.Host = host; - // IsRoot = true; - //} - /// - /// 元素名称 - /// - [Category("设计")] - [Description("元素名称")] - public virtual string Name - { - get - { - //if (((IComponent)this).Site != null) - //{ - // return ((IComponent)this).Site.Name; - //} - return GetValue(); - } - set - { - //if (!string.IsNullOrEmpty(value) && ((IComponent)this).Site != null) - //{ - // ((IComponent)this).Site.Name = value; - //} - SetValue(value); - } - } - /// - /// 键盘焦点 - /// - [UIPropertyMetadata(false, UIPropertyOptions.AffectsRender)] - [Description("键盘焦点")] - public bool IsKeyboardFocused - { - get { return (bool)GetValue(); } - private set { SetValue(value); } - } - /// - /// 获取一个值,该值指示键盘焦点是否位于元素或其可视化树子元素内的任意位置 - /// - [PropertyMetadata(false)] - [Description("获取一个值,该值指示键盘焦点是否位于元素或其可视化树子元素内的任意位置")] - public bool IsKeyboardFocusWithin - { - get { return (bool)GetValue(); } - private set { SetValue(value); } - } - /// - /// 获取焦点的导航方式 - /// - [Description("获取焦点的导航方式")] - [PropertyMetadata(null)] - public NavigationMethod? FocusMethod - { - get { return (NavigationMethod?)GetValue(); } - private set { SetValue(value); } - } - - /// - /// 是否可以获取焦点 - /// - [Description("是否可以获取焦点")] - [PropertyMetadata(false)] - public bool Focusable - { - get { return GetValue(); } - set { SetValue(value); } - } - - /// - /// 与控件关联的用户自定义数据 - /// - [Description("与控件关联的用户自定义数据"), DefaultValue(null), TypeConverter(typeof(StringConverter))] - public object Tag - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 是否有逻辑焦点 - /// - [PropertyMetadata(false)] - [Description("是否有逻辑焦点")] - public bool IsFocused - { - get { return GetValue(); } - private set { SetValue(value); } - } - /// - /// tab键切换元素焦点时候的顺序 - /// - [PropertyMetadata(0)] - [Description("tab键切换元素焦点时候的顺序")] - public int TabIndex - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 按tab键切换焦点显示的聚焦框填充 - /// - [Description("按tab键切换焦点显示的聚焦框填充")] - [PropertyMetadata(typeof(ViewFill), "#000")] - public ViewFill FocusFrameFill - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 按tab键切换焦点显示的聚焦框 - /// - [Description("按tab键切换焦点显示的聚焦框")] - [PropertyMetadata(typeof(Stroke), "1,Dash")] - public Stroke FocusFrameStroke - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 聚焦框到元素边缘距离 - /// - [UIPropertyMetadata(typeof(Thickness), "3", UIPropertyOptions.AffectsRender), Description("聚焦框到元素边缘距离")] - public Thickness FocusFramePadding - { - get { return GetValue(); } - set { SetValue(value); } - } - - /// - /// 图形抗锯齿 - /// - [Description("图形抗锯齿")] - [UIPropertyMetadata(false, UIPropertyOptions.Inherits | UIPropertyOptions.AffectsRender)] - public bool IsAntiAlias - { - get { return GetValue(); } - set { SetValue(value); } - } - - /// - /// 该值指示此元素是否捕获了鼠标 - /// - [PropertyMetadata(false)] - [Description("该值指示此元素是否捕获了鼠标")] - public bool IsMouseCaptured - { - get { return GetValue(); } - private set { SetValue(value); } - } - - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "0", UIPropertyOptions.AffectsMeasure)] - public FloatField MinWidth - { - get { return GetValue(); } - set { SetValue(value); } - } - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "0", UIPropertyOptions.AffectsMeasure)] - public FloatField MinHeight - { - get { return GetValue(); } - set { SetValue(value); } - } - - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "Auto", UIPropertyOptions.AffectsMeasure)] - public FloatField MaxWidth - { - get { return GetValue(); } - set { SetValue(value); } - } - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "Auto", UIPropertyOptions.AffectsMeasure)] - public FloatField MaxHeight - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 是否可以通过鼠标点击到 - /// - [Description("是否可以通过鼠标点击到")] - [PropertyMetadata(true)] - public bool IsHitTestVisible - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 获取或设置一个值,该值指示此元素能否用作拖放操作的目标。 - /// - [Description("获取或设置一个值,该值指示此元素能否用作拖放操作的目标。")] - [UIPropertyMetadata(false, true)] - public bool AllowDrop - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// Z轴 - /// - [Category("布局")] - [Description("Z轴")] - [UIPropertyMetadata(0, UIPropertyOptions.AffectsArrange)] - public int ZIndex - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 默认值为 Auto。此值必须大于或等于 0。 - /// - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "Auto", UIPropertyOptions.AffectsMeasure)] - public virtual FloatField Width - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 默认值为 Auto。此值必须大于或等于 0。 - /// - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "Auto", UIPropertyOptions.AffectsMeasure)] - public virtual FloatField Height - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 非依赖属性 - /// - [Browsable(false), NotCpfProperty] - public virtual SizeField Size - { - get { return new SizeField(Width, Height); } - set { Width = value.Width; Height = value.Height; } - } - - /// - /// 非依赖属性 - /// - [Browsable(false), NotCpfProperty] - public virtual ThicknessField Margin - { - get { return new ThicknessField(MarginLeft, MarginTop, MarginRight, MarginBottom); } - set - { - MarginLeft = value.Left; - MarginTop = value.Top; - MarginRight = value.Right; - MarginBottom = value.Bottom; - } - } - - - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "Auto", UIPropertyOptions.AffectsMeasure)] - public virtual FloatField MarginRight - { - get { return GetValue(); } - set { SetValue(value); } - } - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "Auto", UIPropertyOptions.AffectsMeasure)] - public virtual FloatField MarginBottom - { - get { return GetValue(); } - set { SetValue(value); } - } - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "Auto", UIPropertyOptions.AffectsMeasure)] - public virtual FloatField MarginLeft - { - get { return GetValue(); } - set { SetValue(value); } - } - [Category("布局")] - [UIPropertyMetadata(typeof(FloatField), "Auto", UIPropertyOptions.AffectsMeasure)] - public virtual FloatField MarginTop - { - get { return GetValue(); } - set { SetValue(value); } - } - ///// - ///// 百分比是相对自身 - ///// - //[UIPropertyMetadata(typeof(FloatValue), "0", UIPropertyOptions.AffectsMeasure)] - //public FloatValue PaddingRight - //{ - // get { return (FloatValue)GetValue(); } - // set { SetValue(value); } - //} - ///// - ///// 百分比是相对自身 - ///// - //[UIPropertyMetadata(typeof(FloatValue), "0", UIPropertyOptions.AffectsMeasure)] - //public FloatValue PaddingBottom - //{ - // get { return (FloatValue)GetValue(); } - // set { SetValue(value); } - //} - ///// - ///// 百分比是相对自身 - ///// - //[UIPropertyMetadata(typeof(FloatValue), "0", UIPropertyOptions.AffectsMeasure)] - //public FloatValue PaddingLeft - //{ - // get { return (FloatValue)GetValue(); } - // set { SetValue(value); } - //} - ///// - ///// 百分比是相对自身 - ///// - //[UIPropertyMetadata(typeof(FloatValue), "0", UIPropertyOptions.AffectsMeasure)] - //public FloatValue PaddingTop - //{ - // get { return (FloatValue)GetValue(); } - // set { SetValue(value); } - //} - //internal bool isRoot; - /// - /// 是否为根元素 - /// - [NotCpfProperty] - [Browsable(false)] - public bool IsRoot - { - get { return GetFlag(CoreFlags.isRoot); } - internal set { SetFlag(CoreFlags.isRoot, value); } - } - - /// - /// 根元素 - /// - [NotCpfProperty] - [Browsable(false)] - public virtual View Root - { - get; - internal set; - } - /// - /// 获取一个值,该值指示此元素布局中的子元素的计算大小和位置是否有效。 - /// - [NotCpfProperty] - [Description("获取一个值,该值指示此元素布局中的子元素的计算大小和位置是否有效。")] - public bool IsArrangeValid - { - get { return GetFlag(CoreFlags.IsArrangeValid); } - internal set { SetFlag(CoreFlags.IsArrangeValid, value); } - } - - /// - /// 父级元素 - /// - [NotCpfProperty] - [Browsable(false)] - public virtual UIElement Parent - { - get; - internal set; - } - /// - /// 是否启用 - /// - [UIPropertyMetadata(true, true)] - [Description("是否启用")] - public virtual bool IsEnabled - { - get { return GetValue(); } - set { SetValue(value); } - } - - /// - /// UI元素可见性 - /// - [Category("布局")] - [Description("UI元素可见性")] - [UIPropertyMetadata(Visibility.Visible, UIPropertyOptions.AffectsMeasure)] - public virtual Visibility Visibility - { - get { return (Visibility)GetValue(); } - set { SetValue(value); } - } - /// - /// 光标,用Cursors.***来设置 - /// - [Description("光标")] - [UIPropertyMetadata(typeof(Cursor), "Arrow", true)] - public Cursor Cursor - { - get { return GetValue(); } - set { SetValue(value); } - } - ///// - ///// 元素是否有效,如果为false,将不能显示,而且不参与布局。在布局过程中使用,用来优化布局 - ///// - //[NotCPFProperty] - //public bool Valid - //{ - // get; set; - //} = true; - ///// - ///// 外边距 - ///// - //public virtual Thickness Margin - //{ - // get { return (Thickness)GetValue(MarginProperty); } - // set { SetValue(MarginProperty, value); } - //} - Rect renderBounds; - /// - /// 布局之后相对于根元素的矩形剪辑区域 - /// - [NotCpfProperty] - [Browsable(false)] - [Description("布局之后相对于根元素的矩形剪辑区域")] - public Rect RenderBounds { get { return renderBounds; } } - - /// - /// 渲染变换 - /// - [Browsable(false)] - [Description("渲染变换")] - [UIPropertyMetadata(typeof(Transform), "Identity", UIPropertyOptions.AffectsArrange)] - public virtual Transform RenderTransform - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 渲染原点 - /// - [Category("布局")] - [Description("渲染原点")] - [UIPropertyMetadata(typeof(PointField), "50%,50%", UIPropertyOptions.AffectsArrange)] - public PointField RenderTransformOrigin - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 获取一个值,该值指示鼠标指针是否位于此元素(包括可视树上的子元素)上 - /// - [PropertyMetadata(false)] - [Description("获取一个值,该值指示鼠标指针是否位于此元素(包括可视树上的子元素)上")] - public bool IsMouseOver - { - get { return GetValue(); } - private set { SetValue(value); } - } - /// - /// 获取一个值,该值指示鼠标拖拽指针是否位于此元素(包括可视树上的子元素)上 - /// - [PropertyMetadata(false)] - [Description("获取一个值,该值指示鼠标拖拽指针是否位于此元素(包括可视树上的子元素)上")] - public bool IsDragOver - { - get { return GetValue(); } - private set { SetValue(value); } - } - ///// - ///// 获取一个值,鼠标左键是否按下 - ///// - //[PropertyMetadata(false)] - //public bool IsMouseLeftButtonDown - //{ - // get { return GetValue(); } - // private set { SetValue(value); } - //} - - /// - /// 获取元素呈现的尺寸 - /// - //[NotCpfProperty] - [Description("获取元素呈现的尺寸")] - public Size ActualSize - { - get { return GetValue(); } - protected set { SetValue(value); } - } - /// - /// 元素偏移位置 - /// - [NotCpfProperty] - [Description("元素偏移位置")] - public Point ActualOffset - { - get { return VisualOffset; } - } - /// - /// 获取一个值,该值指示布局度量值返回的当前大小是否有效。 - /// - [NotCpfProperty] - [Description("获取一个值,该值指示布局度量值返回的当前大小是否有效。")] - public bool IsMeasureValid - { - get { return GetFlag(CoreFlags.isMeasureValid); } - private set { SetFlag(CoreFlags.isMeasureValid, value); } - } - /// - /// 获取或设置一个值,该值指示是否应向此元素的大小和位置布局应用布局舍入。 - /// - [PropertyMetadata(false)] - [Description("获取或设置一个值,该值指示是否应向此元素的大小和位置布局应用布局舍入。")] - public bool UseLayoutRounding - { - get { return GetValue(); } - set { SetValue(value); } - } - /// - /// 右键菜单 - /// - [Browsable(false)] - [Description("右键菜单")] - public ContextMenu ContextMenu - { - get { return GetValue(); } - set { SetValue(value); } - } - - /// - /// 使图像无效化,下次更新的时候重绘 - /// - public void Invalidate() - { - var host = Root; - if (host != null) - { - host.Invalidate(renderBounds); - } - } - //public void Invalidate(Rect rect) - //{ - // IView host = Host; - // if (host != null) - // { - // host.Invalidate(GetHostClipBounds(rect)); - // } - //} - /// - /// 是否是该元素的祖先 - /// - /// - /// - public bool IsAncestors(UIElement ancestors) - { - if (ancestors == this) - { - return false; - } - var control = Parent; - while (control != null) - { - if (control == this) - { - return false; - } - else if (control == ancestors) - { - return true; - } - control = control.Parent; - } - return false; - } - - protected override object OnGetDefaultValue(PropertyMetadataAttribute pm) - { - //CpfObject p; - //if (pm.PropertyName != nameof(Parent) && (p = Parent) != null && (pm is UIPropertyMetadataAttribute pma) && pma.Inherits && p.HasProperty(pm.PropertyName)) - //{ - // return p.GetValue(pm.PropertyName); - //} - if (inheritsValues != null && inheritsValues.TryGetValue(pm.PropertyName, out InheritsValue value)) - { - return value.Value; - } - return base.OnGetDefaultValue(pm); - } - protected override bool OnSetValue(string propertyName, ref object value) - { - if (value == null && propertyName == nameof(RenderTransform)) - { - value = Transform.Identity; - } - return base.OnSetValue(propertyName, ref value); - } - - public override bool SetValue(T value, [CallerMemberName] string propertyName = null) - { - if (Root != null && !Threading.Dispatcher.MainThread.CheckAccess()) - { - var r = false; - Invoke(() => - { - r = base.SetValue(value, propertyName); - }); - return r; - } - return base.SetValue(value, propertyName); - } - /// - /// 内部使用,请勿调用 - /// - /// - /// - /// - protected override bool SetValue(object value, in byte propertyIndex) - { - if (Root != null && !Threading.Dispatcher.MainThread.CheckAccess()) - { - var r = false; - var pi = propertyIndex; - Invoke(() => - { - r = base.SetValue(value, pi); - }); - return r; - } - return base.SetValue(value, in propertyIndex); - } - - public override T GetValue([CallerMemberName] string propertyName = null) - { - if (Root != null && !Threading.Dispatcher.MainThread.CheckAccess()) - { - T r = default; - Invoke(() => - { - r = base.GetValue(propertyName); - }); - return r; - } - return base.GetValue(propertyName); - } - /// - /// 内部使用,请勿调用 - /// - /// - /// - protected override object GetValue(in byte index) - { - if (Root != null && !Threading.Dispatcher.MainThread.CheckAccess()) - { - object r = default; - var i = index; - Invoke(() => - { - r = base.GetValue(i); - }); - return r; - } - return base.GetValue(index); - } - [NotCpfProperty] - bool inheritsSet { set { SetFlag(CoreFlags.inheritsSet, value); } get { return GetFlag(CoreFlags.inheritsSet); } } - - [PropertyChanged(nameof(Effect))] - void RegisterEffect(object newValue, object oldValue, PropertyMetadataAttribute attribute) - { - effect = newValue as Effects.Effect; - } - - [PropertyChanged(nameof(ZIndex))] - void RegisterZIndex(object newValue, object oldValue, PropertyMetadataAttribute attribute) - { - UIElement parent = Parent; - if (parent != null) - { - parent.children.InvalidateZIndex(); - } - } - [PropertyChanged(nameof(RenderTransform))] - void RegisterRenderTransform(object newValue, object oldValue, PropertyMetadataAttribute attribute) - { - VisualTransform = RenderTransform; - } - [PropertyChanged(nameof(ToolTip))] - void RegisterToolTip(object newValue, object oldValue, PropertyMetadataAttribute attribute) - { - if (toolTipElement) - { - toolTipElement.Dispose(); - toolTipElement = null; - } - if (newValue != null) - { - UIElement element = newValue as UIElement; - if (element != null) - { - toolTipElement = element; - } - else - { - toolTipElement = new Border - { - Name = "tooltipContent", - UseLayoutRounding = true, - BorderStroke = new Stroke(1), - MarginTop = 1, - MarginRight = 1, - MarginLeft = 1, - MarginBottom = 1, - BorderFill = "#aaa", - Background = "#fff", - Child = new ContentControl { Content = newValue, MarginBottom = 2, MarginLeft = 4, MarginRight = 4, MarginTop = 2 } - }; - } - } - } - - [PropertyChanged(nameof(Visibility))] - void RegisterVisibility(object newValue, object oldValue, PropertyMetadataAttribute attribute) - { - Invalidate(); - if ((Visibility)newValue == Visibility.Collapsed) - { - if (IsMouseOver) - { - var e = new MouseEventArgs(Root.InputManager.MouseDevice, this, false, false, false, new Point()); - Root.InputManager.MouseDevice.MouseLeave(this, e); - } - if (IsKeyboardFocusWithin || IsFocused) - { - Root.InputManager.KeyboardDevice.SetFocus(null); - InnerLostFocus(); - } - } - } - - - - - protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata) - { - //if (propertyName == nameof(RenderTransform)) - //{ - // this.VisualTransform = RenderTransform; - //} - //else - //if (propertyName == nameof(ZIndex)) - //{ - // UIElement parent = Parent; - // if (parent != null) - // { - // parent.children.InvalidateZIndex(); - // } - //} - //else - //if (propertyName == nameof(Effect)) - //{ - // effect = newValue as Effects.Effect; - //} - //else - //if (propertyName == nameof(ToolTip)) - //{ - // if (toolTipElement) - // { - // toolTipElement.Dispose(); - // toolTipElement = null; - // } - // if (newValue != null) - // { - // UIElement element = newValue as UIElement; - // if (element != null) - // { - // toolTipElement = element; - // } - // else - // { - // toolTipElement = new Control { UseLayoutRounding = true, BorderStroke = new Stroke(1), MarginTop = 1, MarginRight = 1, MarginLeft = 1, MarginBottom = 1, BorderFill = "#aaa", Background = "#fff", Children = { new ContentControl { Content = newValue.ToString(), MarginBottom = 2, MarginLeft = 4, MarginRight = 4, MarginTop = 2 } } }; - // } - // } - //} - //else - //if (propertyName == nameof(Visibility)) - //{ - // if ((Visibility)newValue == Visibility.Collapsed) - // { - // //IsMouseOver = false; - // if (IsMouseOver) - // { - // var e = new MouseEventArgs(Root.InputManager.MouseDevice, this, false, false, false, new Point(), 0); - // //RaiseDeviceEvent(e, EventType.MouseLeave); - // Root.InputManager.MouseDevice.MouseLeave(this, e); - // } - // //foreach (var item in Find().Where(a => a.IsMouseOver)) - // //{ - // // //item.IsMouseOver = false; - // // //item.IsMouseLeftButtonDown = false; - // //} - // if (IsKeyboardFocusWithin || IsFocused) - // { - // Root.InputManager.KeyboardDevice.SetFocus(null); - // InnerLostFocus(); - // } - // } - //} - //if (Name == "more" && propertyName == "MarginLeft") - //{ - // Debug.WriteLine(newValue); - //} - base.OnPropertyChanged(propertyName, oldValue, newValue, propertyMetadata); - var data = propertyMetadata as UIPropertyMetadataAttribute; - if (data != null) - { - if (data.Inherits) - { - - if (!inheritsSet) - { - for (int i = 0; i < Children.Count; i++) - { - Inherits(children[i], propertyName, oldValue, newValue); - } - } - } - if (data.AffectsMeasure) - { - InvalidateMeasure(); - //Parent?.OnChildInvalidateMeasure(this); - } - else if (data.AffectsArrange) - { - InvalidateArrange(); - //Parent?.OnChildInvalidateArrange(this); - } - else if (data.AffectsRender) - { - Invalidate(); - } - var notify = oldValue as INotifyPropertyChanged; - if (notify != null) - { - //notify.PropertyChanged -= Notify_PropertyChanged; - Binding.CancellationPropertyChanged(notify, Notify_PropertyChanged); - if (notifyList != null) - { - if (notifyList.TryGetValue(notify, out var p)) - { - p.Remove(data); - if (p.Count == 0) - { - notifyList.Remove(notify); - } - } - } - } - notify = newValue as INotifyPropertyChanged; - if (notify != null) - { - //notify.PropertyChanged += Notify_PropertyChanged; - Binding.RegisterPropertyChanged(notify, Notify_PropertyChanged); - if (notifyList == null) - { - notifyList = new HybridDictionary>(); - } - if (!notifyList.TryGetValue(notify, out var p)) - { - notifyList.Add(notify, new HashSet { data }); - } - else - { - p.Add(data); - } - } - } - - if (triggers != null) - { - var c = triggers.Count; - for (int i = 0; i < c; i++) - { - if (i >= triggers.Count) - { - break; - } - var t = triggers[i]; - if (t.Property == propertyName) - { - var set = t.Condition(this); - if (t.TargetRelation != null && t.TargetRelation != Relation.Me) - { - foreach (var item in t.TargetRelation.Query(this)) - { - SetTrigger(t, item, set); - } - } - else - { - SetTrigger(t, this, set); - } - } - } - } - - } - - protected override void OnAttachedChanged(Type ownerType, string propertyName, object defaultValue, object oldValue, object newValue) - { - base.OnAttachedChanged(ownerType, propertyName, defaultValue, oldValue, newValue); - if (triggers != null) - { - var c = triggers.Count; - for (int i = 0; i < c; i++) - { - if (i >= triggers.Count) - { - break; - } - var t = triggers[i]; - if (t.Property == ownerType.Name + "." + propertyName) - { - var set = t.Condition(this); - if (t.TargetRelation != null && t.TargetRelation != Relation.Me) - { - foreach (var item in t.TargetRelation.Query(this)) - { - SetTrigger(t, item, set); - } - } - else - { - SetTrigger(t, this, set); - } - } - } - } - } - - private void SetTrigger(Trigger t, UIElement target, bool setTriggerValue, bool onAdd = false) - { - if (setTriggerValue) - { - if (t.Animation != null && Root != null && (!onAdd || PlayAnimationOnAddTrigger)) - { - t.Animation.Start(this, target, t.AnimationDuration, t.AnimationIterationCount, t.AnimationEndBehavior, t); - } - foreach (var item in t.Setters) - { - if (target.HasProperty(item.Key)) - { - target.SetTriggerValue(item.Key, t, item.Value); - } - } - } - else - { - //foreach (var item in t.Setters) - //{ - // target.ClearTriggerValue(t, item.Key); - //} - if (t.Animation != null) - { - t.Animation.Remove(target); - } - if (t.SetPropertys != null) - { - if (t.SetPropertys.TryGetValue(target, out List ps)) - { - foreach (var item in ps) - { - target.ClearTriggerValue(t, item); - } - } - - //t.SetPropertys.Clear(); - } - } - } - - private void Notify_PropertyChanged(object sender, PropertyChangedEventArgs e) - { - if (notifyList != null) - { - if (notifyList.TryGetValue((sender as INotifyPropertyChanged), out var p)) - { - bool AffectsMeasure = false; - bool AffectsArrange = false; - bool AffectsRender = false; - foreach (var item in p) - { - AffectsMeasure = AffectsMeasure || item.AffectsMeasure; - AffectsRender = AffectsRender || item.AffectsRender; - AffectsArrange = AffectsArrange || item.AffectsArrange; - } - - if (AffectsMeasure) - { - InvalidateMeasure(); - //Parent?.OnChildInvalidateMeasure(this); - } - else if (AffectsArrange) - { - InvalidateArrange(); - //Parent?.OnChildInvalidateArrange(this); - } - else if (AffectsRender) - { - Invalidate(); - } - } - } - } - - void Inherits(UIElement element, string propertyName, object oldValue, object newValue) - { - if (!element.HasLocalOrStyleValue(propertyName, out var p)) - { - element.inheritsSet = true; - //var p = element.GetPropertyMetadata(propertyName); - if (p != null) - { - if (p is UIPropertyMetadataAttribute ui && ui.Inherits) - { - element.inheritsValues.Remove(propertyName); - element.inheritsValues.Add(propertyName, new InheritsValue { Value = newValue, ValueForm = ValueForm.Property }); - } - element.OnPropertyChanged(propertyName, oldValue, newValue, p); - } - element.inheritsSet = false; - //if (propertyName != nameof(DataContext) || !element.HasLocalOrStyleValue(propertyName, out p)) - //{ - for (int i = 0; i < element.Children.Count; i++) - { - Inherits(element.children[i], propertyName, oldValue, newValue); - } - //} - } - } - - internal override void OnSetValue(string propertyName, PropertyMetadataAttribute property, ValueForm valueForm, object newValue) - { - if (property is UIPropertyMetadataAttribute ui && ui.Inherits) - { - inheritsValues.Remove(propertyName); - inheritsValues.Add(propertyName, new InheritsValue { Value = newValue, ValueForm = valueForm }); - } - } - - internal override void OnClearLocalValue(string propertyName, EffectiveValue value) - { - if (inheritsValues.TryGetValue(propertyName, out InheritsValue value1) && value1.ValueForm == ValueForm.Property) - { - inheritsValues.Remove(propertyName); - } - } - internal override void OnClearTriggerValue(string propertyName, EffectiveValue value) - { - if (value.TriggerValue == null || value.TriggerValue.Count == 0) - { - if (inheritsValues.TryGetValue(propertyName, out InheritsValue value1) && value1.ValueForm == ValueForm.Trigger) - { - inheritsValues.Remove(propertyName); - } - } - } - - internal override void OnClearAnimationValue(string propertyName, EffectiveValue value) - { - if (value.AnimationValue == null || value.AnimationValue.Count == 0) - { - if (inheritsValues.TryGetValue(propertyName, out InheritsValue value1) && value1.ValueForm == ValueForm.Animation) - { - inheritsValues.Remove(propertyName); - } - } - } - - internal override void OnClearStyleValue(string propertyName, EffectiveValue value) - { - if (value.styleValues == null || value.styleValues.Count == 0) - { - if (inheritsValues.TryGetValue(propertyName, out InheritsValue value1) && value1.ValueForm == ValueForm.Style) - { - inheritsValues.Remove(propertyName); - } - } - } - - /// - /// 获取在布局流程的度量传递过程中此元素计算所得的大小,包含margin。其实就是能包含所有内容的最小尺寸 - /// - /// - [NotCpfProperty] - public Size DesiredSize - { - get { return desiredSize; } - } - /// - /// 在派生类中重写时,测量子元素或者内容在布局中所需的大小,availableSize不包含当前对象的Margin和Padding,并确定由 UIElement 派生的类的大小。 - /// - /// 一般不要使用该属性参与计算 - /// 此元素基于其对子元素大小的计算确定它在布局期间所需要的大小。 - protected virtual Size MeasureOverride(in Size availableSize) - { - Size contentDesiredSize = new Size(); - - if (children != null) - { - foreach (UIElement item in Children) - { - item.Measure(availableSize); - contentDesiredSize.Width = Math.Max(contentDesiredSize.Width, item.DesiredSize.Width); - contentDesiredSize.Height = Math.Max(contentDesiredSize.Height, item.DesiredSize.Height); - } - } - - return contentDesiredSize; - } - /// - /// 测量期望尺寸 - /// - /// 一般不要使用该属性 - public void Measure(in Size availableSize) - { - if (!IsMeasureValid || (_previousMeasure != availableSize && (Width.IsAuto || Width.Unit != Unit.Default || Height.IsAuto || Height.Unit != Unit.Default))) - { - var previousDesiredSize = desiredSize; - - - IsMeasureValid = true; - //try - //{ - //_measuring = true; - desiredSize = MeasureCore(availableSize);//.Constrain(availableSize); - //Console.WriteLine(this.ToString() + ":" + desiredSize.ToString()); - //} - //finally - //{ - // //_measuring = false; - //} - - //if (IsInvalidSize(desiredSize)) - //{ - // throw new InvalidOperationException("Invalid size returned for Measure."); - //} - - _previousMeasure = availableSize; - - //Logger.Verbose(LogArea.Layout, this, "Measure requested {DesiredSize}", DesiredSize); - - if (DesiredSize != previousDesiredSize) - { - Parent?.OnChildDesiredSizeChanged(this); - this.RaiseEvent(EventArgs.Empty, nameof(DesiredSizeChanged)); - } - } - - } - - internal static float RoundLayoutValue(float value, float dpiScale) - { - float newValue; - - // If DPI == 1, don't use DPI-aware rounding. - if (!FloatUtil.AreClose(dpiScale, 1f)) - { - newValue = (float)Math.Round(value * dpiScale) / dpiScale; - // If rounding produces a value unacceptable to layout (NaN, Infinity or MaxValue), use the original value. - if (FloatUtil.IsNaN(newValue) || - float.IsInfinity(newValue) || - FloatUtil.AreClose(newValue, float.MaxValue)) - { - newValue = value; - } - } - else - { - newValue = (float)Math.Round(value); - } - - return newValue; - } - protected virtual void OnChildDesiredSizeChanged(UIElement child) - { - if (((!Width.IsAuto && Width.Unit != Unit.Percent)) && ((!Height.IsAuto && Height.Unit != Unit.Percent))) - { - InvalidateArrange(); - } - else - { - InvalidateMeasure(); - } - } - - static Type panelType = typeof(Panel); - /// - /// 测量期望尺寸 - /// - /// 相当于父容器能提供的尺寸,如果值为PositiveInfinity,则父容器未定义尺寸依赖子元素的尺寸 - /// The desired size for the control. - protected virtual Size MeasureCore(in Size availableSize) - { - if (Visibility != Visibility.Collapsed) - { - var l = MarginLeft; - var t = MarginTop; - var r = MarginRight; - var b = MarginBottom; - var w = Width; - var h = Height; - var maxw = MaxWidth; - var maxh = MaxHeight; - var minw = MinWidth; - var minh = MinHeight; - - var constrainedWidth = float.PositiveInfinity;//可以提供的最大尺寸 - var constrainedHeight = float.PositiveInfinity; - - if (!l.IsAuto && !r.IsAuto) - { - constrainedWidth = Math.Max(0, availableSize.Width - l.GetActualValue(availableSize.Width) - r.GetActualValue(availableSize.Width)); - } - if (!w.IsAuto) - { - //if (w.Unit == Unit.Percent && Parent != null && Parent.Width.IsAuto) - //{ - // constrainedWidth = float.PositiveInfinity; - //} - //else - //{ - constrainedWidth = Math.Max(0, w.GetActualValue(availableSize.Width)); - //} - } - if (!float.IsInfinity(constrainedWidth) && !maxw.IsAuto && !float.IsInfinity(availableSize.Width)) - { - var max = maxw.GetActualValue(availableSize.Width); - if (constrainedWidth > max) - { - constrainedWidth = max; - } - } - if (!minw.IsAuto) - { - var min = minw.GetActualValue(availableSize.Width); - if (constrainedWidth < min) - { - constrainedWidth = min; - } - } - - if (!t.IsAuto && !b.IsAuto) - { - constrainedHeight = Math.Max(0, availableSize.Height - t.GetActualValue(availableSize.Height) - b.GetActualValue(availableSize.Height)); - } - if (!h.IsAuto) - { - //if (h.Unit == Unit.Percent && Parent != null && Parent.Height.IsAuto) - //{ - // constrainedHeight = float.PositiveInfinity; - //} - //else - //{ - constrainedHeight = Math.Max(0, h.GetActualValue(availableSize.Height)); - //} - } - - if (!float.IsInfinity(constrainedHeight) && !maxh.IsAuto && !float.IsInfinity(availableSize.Height)) - { - var max = maxh.GetActualValue(availableSize.Height); - if (constrainedHeight > max) - { - constrainedHeight = max; - } - } - if (!minh.IsAuto) - { - var min = minh.GetActualValue(availableSize.Height); - if (constrainedHeight < min) - { - constrainedHeight = min; - } - } - - //内容尺寸 - var measured = MeasureOverride(new Size(constrainedWidth, constrainedHeight)); - var width = measured.Width; - var height = measured.Height; - - var wPercent = float.NaN; - var hPercent = float.NaN; - if (!w.IsAuto) - { - if (w.Unit == Unit.Default || (!float.IsInfinity(availableSize.Width) && !float.IsNaN(availableSize.Width))) - { - width = w.GetActualValue(availableSize.Width); - } - else - { - wPercent = w.Value; - } - } - if (!h.IsAuto) - { - if (h.Unit == Unit.Default || (!float.IsInfinity(availableSize.Height) && !float.IsNaN(availableSize.Height))) - { - height = h.GetActualValue(availableSize.Height); - } - else - { - hPercent = h.Value; - } - } - float pW;//计算如果是百分比布局为100%的时候占用的尺寸 - if (!float.IsNaN(wPercent)) - { - pW = width / wPercent; - } - else - { - pW = width; - } - float pH; - if (!float.IsNaN(hPercent)) - { - pH = height / hPercent; - } - else - { - pH = height; - } - - - if (!minw.IsAuto) - { - if (minw.Unit == Unit.Default) - { - if (width < minw.Value) - { - width = minw.Value; - } - } - else - { - if (!float.IsNaN(pW)) - { - var min = pW * minw.Value; - if (min > width) - { - width = min; - } - } - } - } - if (!minh.IsAuto) - { - if (minh.Unit == Unit.Default) - { - if (height < minh.Value) - { - height = minh.Value; - } - } - else - { - if (!float.IsNaN(pH)) - { - var min = pH * minh.Value; - if (min > height) - { - height = min; - } - } - } - } - if (!maxw.IsAuto) - { - if (maxw.Unit == Unit.Default) - { - if (width > maxw.Value) - { - width = maxw.Value; - } - } - else - { - if (!float.IsNaN(pW)) - { - var max = pW * maxw.Value; - if (max < width) - { - width = max; - } - } - } - } - if (!maxh.IsAuto) - { - if (maxh.Unit == Unit.Default) - { - if (height > maxh.Value) - { - height = maxh.Value; - } - } - else - { - if (!float.IsNaN(pH)) - { - var max = pH * maxh.Value; - if (max < height) - { - height = max; - } - } - } - } - - if (!l.IsAuto) - { - if (l.Unit == Unit.Default) - { - width += l.Value; - } - else - { - if (float.IsNaN(availableSize.Width) || float.IsPositiveInfinity(availableSize.Width)) - { - width += pW * l.Value; - } - else - { - width += availableSize.Width * l.Value; - } - } - } - if (!r.IsAuto) - { - if (r.Unit == Unit.Default) - { - width += r.Value; - } - else - { - if (float.IsNaN(availableSize.Width) || float.IsPositiveInfinity(availableSize.Width)) - { - width += pW * r.Value; - } - else - { - width += availableSize.Width * r.Value; - } - } - } - if (!t.IsAuto) - { - if (t.Unit == Unit.Default) - { - height += t.Value; - } - else - { - if (float.IsPositiveInfinity(availableSize.Height) || float.IsNaN(availableSize.Height)) - { - height += pH * t.Value; - } - else - { - height += availableSize.Height * t.Value; - } - } - } - if (!b.IsAuto) - { - if (b.Unit == Unit.Default) - { - height += b.Value; - } - else - { - if (float.IsPositiveInfinity(availableSize.Height) || float.IsNaN(availableSize.Height)) - { - height += pH * b.Value; - } - else - { - height += availableSize.Height * b.Value; - } - } - } - - - - //if (wPercent != 0) - //{ - // width = width / wPercent; - // width = Math.Max(width, constrainedWidth); - //} - //if (hPercent != 0) - //{ - // height = height / hPercent; - // height = Math.Max(height, constrainedHeight); - //} - - if (UseLayoutRounding) - { - var scale = Root.RenderScaling; - width = (float)Math.Ceiling(width * scale) / scale; - height = (float)Math.Ceiling(height * scale) / scale; - } - - return new Size(width, height); - } - else - { - return new Size(); - } - } - //protected virtual Size MeasureCore(in Size availableSize) - //{ - // if (Visibility != Visibility.Collapsed) - // { - // var l = MarginLeft; - // var t = MarginTop; - // var r = MarginRight; - // var b = MarginBottom; - // var w = Width; - // var h = Height; - // var maxw = MaxWidth; - // var maxh = MaxHeight; - // var minw = MinWidth; - // var minh = MinHeight; - - // var constrainedWidth = availableSize.Width;//可以提供的最大尺寸 - // var constrainedHeight = availableSize.Height; - - // if (!l.IsAuto && !r.IsAuto) - // { - // constrainedWidth = constrainedWidth - l.GetActualValue(availableSize.Width); - // constrainedWidth = constrainedWidth - r.GetActualValue(availableSize.Width); - // } - // if (!w.IsAuto) - // { - // constrainedWidth = w.GetActualValue(availableSize.Width); - // } - // if (!maxw.IsAuto) - // { - // var max = maxw.GetActualValue(availableSize.Width); - // if (constrainedWidth > max) - // { - // constrainedWidth = max; - // } - // } - // if (!minw.IsAuto) - // { - // var min = minw.GetActualValue(availableSize.Width); - // if (constrainedWidth < min) - // { - // constrainedWidth = min; - // } - // } - - // if (!t.IsAuto && !b.IsAuto) - // { - // constrainedHeight = constrainedHeight - t.GetActualValue(availableSize.Height); - // //} - // //if () - // //{ - // constrainedHeight = constrainedHeight - b.GetActualValue(availableSize.Height); - // } - // if (!h.IsAuto) - // { - // constrainedHeight = h.GetActualValue(availableSize.Height); - // } - - // if (!maxh.IsAuto) - // { - // var max = maxh.GetActualValue(availableSize.Height); - // if (constrainedHeight > max) - // { - // constrainedHeight = max; - // } - // } - // if (!minh.IsAuto) - // { - // var min = minh.GetActualValue(availableSize.Height); - // if (constrainedHeight < min) - // { - // constrainedHeight = min; - // } - // } - - // //var margin = new Thickness(); - // //if (!IsRoot) - // //{ - // // margin = new Thickness(l.GetActualValue(availableSize.Width), t.GetActualValue(availableSize.Height), r.GetActualValue(availableSize.Width), b.GetActualValue(availableSize.Height)); - // //} - - // //.Deflate(margin); - // //var padding = new Thickness(pl.GetActualValue(availableSize.Width), pt.GetActualValue(availableSize.Height), pr.GetActualValue(availableSize.Width), pb.GetActualValue(availableSize.Height)); - - // //内容尺寸 - // var measured = MeasureOverride(new Size(constrainedWidth, constrainedHeight)); - // var width = measured.Width; - // var height = measured.Height; - - - - // if (!w.IsAuto) - // { - // width = w.GetActualValue(availableSize.Width); - // } - // if (!h.IsAuto) - // { - // height = h.GetActualValue(availableSize.Height); - // } - // if (!minw.IsAuto) - // { - // var min = minw.GetActualValue(availableSize.Width); - // if (width < min) - // { - // width = min; - // } - // } - // if (!minh.IsAuto) - // { - // var min = minh.GetActualValue(availableSize.Height); - // if (height < min) - // { - // height = min; - // } - // } - // if (!maxw.IsAuto) - // { - // var max = maxw.GetActualValue(availableSize.Width); - // if (width > max) - // { - // width = max; - // } - // } - // if (!maxh.IsAuto) - // { - // var max = maxh.GetActualValue(availableSize.Height); - // if (height > max) - // { - // height = max; - // } - // } - - // if (!l.IsAuto) - // { - // width += l.GetActualValue(availableSize.Width); - // } - // if (!r.IsAuto) - // { - // width += r.GetActualValue(availableSize.Width); - // } - // if (!t.IsAuto) - // { - // height += t.GetActualValue(availableSize.Height); - // } - // if (!b.IsAuto) - // { - // height += b.GetActualValue(availableSize.Height); - // } - - - // if (UseLayoutRounding) - // { - // var scale = Root.Scaling; - // width = (float)Math.Ceiling(width * scale) / scale; - // height = (float)Math.Ceiling(height * scale) / scale; - // } - - // return new Size(Math.Max(0, width), Math.Max(0, height)); - // } - // else - // { - // return new Size(); - // } - //} - /// - /// Arranges the control and its children. - /// - /// The control's new bounds. - public void Arrange(Rect rect) - { - Root.LayoutManager._toArrange.Remove(this); - if (IsInvalidRect(rect)) - { - throw new InvalidOperationException("Invalid Arrange rectangle."); - } - - if (!IsMeasureValid) - { - Measure(_previousMeasure ?? rect.Size); - } - - if (!IsArrangeValid || _previousArrange != rect) - { - IsArrangeValid = true; - _previousArrange = rect; - - if (Visibility != Visibility.Collapsed) - { - ArrangeCore(rect); - contentBounds = new Rect(VisualOffset, ActualSize); - } - else - { - renderBounds = new Rect(); - } - - OnLayoutUpdated(); - if (Parent != null && Parent.IsRoot) - { - Parent.viewRenderRect = true; - } - } - } - - /// - /// 获取在View上对应的剪辑区域 - /// - /// - /// - public Rect GetHostClipBounds(Rect rect) - { - UIElement parent = this.Parent; - var bounds = this.GetClipBounds(rect); - while (parent != null) - { - bounds = parent.GetClipBounds(bounds); - parent = parent.Parent; - } - return bounds; - } - [NotCpfProperty] - bool transform { set { SetFlag(CoreFlags.transform, value); } get { return GetFlag(CoreFlags.transform); } } - internal void RendRect() - { - previousRenderRect = renderBounds; - UIElement parent = this.Parent; - renderBounds = this.GetClipBounds(); - if (parent != null) - { - transform = parent.transform || VisualTransform != Transform.Identity; - } - else - { - transform = VisualTransform != Transform.Identity; - } - if (transform) - { - while (parent != null) - { - renderBounds = parent.GetClipBounds(renderBounds); - parent = parent.Parent; - } - } - else - { - if (parent != null) - { - renderBounds = new Rect(renderBounds.X + parent.renderBounds.X, renderBounds.Y + parent.renderBounds.Y, renderBounds.Width, renderBounds.Height); - } - } - if (effect != null) - { - renderBounds = effect.OverrideRenderRect(renderBounds); - } - var rect = previousRenderRect; - rect.Union(renderBounds); - Root.Invalidate(rect); - } - /// - /// 获取该元素相对Root的最终变换矩阵 - /// - /// - public Matrix GetMatrixToRoot() - { - if (IsRoot || Root == null) - { - return Matrix.Identity; - } - List elements = new List(); - elements.Add(this); - var parent = Parent; - while (parent != null && !parent.IsRoot) - { - elements.Add(parent); - parent = parent.Parent; - } - elements.Reverse(); - var mat = Matrix.Identity; - foreach (var item in elements) - { - Rect rect = item.GetContentBounds(); - var op = item.RenderTransformOrigin; - mat.TranslatePrepend(rect.X + op.X.GetActualValue(rect.Width), rect.Y + op.Y.GetActualValue(rect.Height)); - mat.Prepend(item.RenderTransform.Value); - mat.TranslatePrepend(-op.X.GetActualValue(rect.Width), -op.Y.GetActualValue(rect.Height)); - } - return mat; - } - /// - /// 获取该元素相对Parent的变换矩阵 - /// - /// - /// - public Matrix GetMatrixToParent(UIElement element) - { - if (IsRoot || Root == null || element.Root != Root) - { - return Matrix.Identity; - } - List elements = new List(); - elements.Add(this); - var parent = Parent; - while (parent != null && !parent.IsRoot && element != parent) - { - elements.Add(parent); - parent = parent.Parent; - } - elements.Reverse(); - var mat = Matrix.Identity; - foreach (var item in elements) - { - Rect rect = item.GetContentBounds(); - var op = item.RenderTransformOrigin; - mat.TranslatePrepend(rect.X + op.X.GetActualValue(rect.Width), rect.Y + op.Y.GetActualValue(rect.Height)); - mat.Prepend(item.RenderTransform.Value); - mat.TranslatePrepend(-op.X.GetActualValue(rect.Width), -op.Y.GetActualValue(rect.Height)); - } - return mat; - } - - /// - /// The default implementation of the control's arrange pass. - /// - /// The control's new bounds. - /// - /// This method calls which is probably the method you - /// want to override in order to modify a control's arrangement. - /// - protected virtual void ArrangeCore(in Rect finalRect) - { - var l = MarginLeft; - var t = MarginTop; - var r = MarginRight; - var b = MarginBottom; - var w = Width; - var h = Height; - var maxw = MaxWidth; - var maxh = MaxHeight; - var minw = MinWidth; - var minh = MinHeight; - - var scale = Root.RenderScaling; - - float constrainedWidth; - float constrainedHeight; - bool isPanel = true; - var p = Parent; - if (p == null || !(p is Panel) || p.Type == panelType) - {//普通元素布局 - isPanel = false; - if (!l.IsAuto && !r.IsAuto) - { - constrainedWidth = finalRect.Width - l.GetActualValue(finalRect.Width) - r.GetActualValue(finalRect.Width); - } - else - { - constrainedWidth = desiredSize.Width - l.GetActualValue(finalRect.Width) - r.GetActualValue(finalRect.Width); - } - if (!w.IsAuto) - { - constrainedWidth = w.GetActualValue(finalRect.Width); - } - if (!maxw.IsAuto) - { - var max = maxw.GetActualValue(finalRect.Width); - if (constrainedWidth > max) - { - constrainedWidth = max; - } - } - if (!minw.IsAuto) - { - var min = minw.GetActualValue(finalRect.Width); - if (constrainedWidth < min) - { - constrainedWidth = min; - } - } - - if (!t.IsAuto && !b.IsAuto) - { - constrainedHeight = finalRect.Height - t.GetActualValue(finalRect.Height) - b.GetActualValue(finalRect.Height); - } - else - { - constrainedHeight = desiredSize.Height - t.GetActualValue(finalRect.Height) - b.GetActualValue(finalRect.Height); - } - if (!h.IsAuto) - { - constrainedHeight = h.GetActualValue(finalRect.Height); - } - - if (!maxh.IsAuto) - { - var max = maxh.GetActualValue(finalRect.Height); - if (constrainedHeight > max) - { - constrainedHeight = max; - } - } - if (!minh.IsAuto) - { - var min = minh.GetActualValue(finalRect.Height); - if (constrainedHeight < min) - { - constrainedHeight = min; - } - } - } - else - {//panel的继承的布局容器布局 - //if (this is TextBlock textBlock && textBlock.Text == "跨列") - //{ - - //} - if (!w.IsAuto) - { - constrainedWidth = w.GetActualValue(finalRect.Width); - } - else - { - if (!l.IsAuto && !r.IsAuto) - { - constrainedWidth = finalRect.Width - l.GetActualValue(finalRect.Width) - r.GetActualValue(finalRect.Width); - } - else - { - constrainedWidth = desiredSize.Width - l.GetActualValue(finalRect.Width) - r.GetActualValue(finalRect.Width); - } - } - if (!w.IsAuto) - { - constrainedWidth = w.GetActualValue(finalRect.Width); - } - if (!maxw.IsAuto) - { - var max = maxw.GetActualValue(finalRect.Width); - if (constrainedWidth > max) - { - constrainedWidth = max; - } - } - if (!minw.IsAuto) - { - var min = minw.GetActualValue(finalRect.Width); - if (constrainedWidth < min) - { - constrainedWidth = min; - } - } - if (!h.IsAuto) - { - constrainedHeight = h.GetActualValue(finalRect.Height); - } - else - { - if (!t.IsAuto && !b.IsAuto) - { - constrainedHeight = finalRect.Height - t.GetActualValue(finalRect.Height) - b.GetActualValue(finalRect.Height); - } - else - { - constrainedHeight = desiredSize.Height - t.GetActualValue(finalRect.Height) - b.GetActualValue(finalRect.Height); - } - } - if (!h.IsAuto) - { - constrainedHeight = h.GetActualValue(finalRect.Height); - } - - if (!maxh.IsAuto) - { - var max = maxh.GetActualValue(finalRect.Height); - if (constrainedHeight > max) - { - constrainedHeight = max; - } - } - if (!minh.IsAuto) - { - var min = minh.GetActualValue(finalRect.Height); - if (constrainedHeight < min) - { - constrainedHeight = min; - } - } - } - //var s = _previousArrangeResultSize; - //if (_previousArrangeFinalSize != size) - //{ - var size = new Size(constrainedWidth, constrainedHeight); - size = ArrangeOverride(size); - // _previousArrangeResultSize = s; - // _previousArrangeFinalSize = size; - //} - if (!l.IsAuto && !r.IsAuto) - { - size.Width = finalRect.Width - l.GetActualValue(finalRect.Width) - r.GetActualValue(finalRect.Width); - } - if (!t.IsAuto && !b.IsAuto) - { - size.Height = finalRect.Height - t.GetActualValue(finalRect.Height) - b.GetActualValue(finalRect.Height); - } - - if (!w.IsAuto) - { - size.Width = Math.Max(0, w.GetActualValue(finalRect.Width)); - } - if (!h.IsAuto) - { - size.Height = Math.Max(0, h.GetActualValue(finalRect.Height)); - } - - if (!minw.IsAuto) - { - size.Width = Math.Max(size.Width, minw.GetActualValue(finalRect.Width)); - } - if (!minh.IsAuto) - { - size.Height = Math.Max(size.Height, minh.GetActualValue(finalRect.Height)); - } - if (!maxw.IsAuto) - { - size.Width = Math.Min(size.Width, maxw.GetActualValue(finalRect.Width)); - } - if (!maxh.IsAuto) - { - size.Height = Math.Min(size.Height, maxh.GetActualValue(finalRect.Height)); - } - - - var originX = finalRect.X + l.GetActualValue(finalRect.Width); - var originY = finalRect.Y + t.GetActualValue(finalRect.Height); - if (l.IsAuto && !r.IsAuto) - { - originX = finalRect.Right - size.Width - r.GetActualValue(finalRect.Width); - } - else if (l.IsAuto && r.IsAuto) - { - originX = finalRect.Left + (finalRect.Width - size.Width) / 2; - if (isPanel && size.Width > finalRect.Width) - { - originX = finalRect.X; - } - } - if (t.IsAuto && !b.IsAuto) - { - originY = finalRect.Bottom - size.Height - b.GetActualValue(finalRect.Height); - } - else if (t.IsAuto && b.IsAuto) - { - originY = finalRect.Top + (finalRect.Height - size.Height) / 2; - if (isPanel && size.Height > finalRect.Height) - { - originY = finalRect.Y; - } - } - if (UseLayoutRounding) - { - originX = (float)Math.Floor(originX * scale) / scale; - originY = (float)Math.Floor(originY * scale) / scale; - size.Width = (float)Math.Ceiling(size.Width * scale) / scale; - size.Height = (float)Math.Ceiling(size.Height * scale) / scale; - } - - var offset = new Point(originX, originY); - VisualOffset = offset; - if (ActualSize != size) - { - ActualSize = size; - viewRenderRect = true; - } - } - [NotCpfProperty] - internal bool viewRenderRect { get { return GetFlag(CoreFlags.viewRenderRect); } set { SetFlag(CoreFlags.viewRenderRect, value); } } - //protected virtual void ArrangeCore(in Rect finalRect) - //{ - // var l = MarginLeft; - // var t = MarginTop; - // var r = MarginRight; - // var b = MarginBottom; - // var w = Width; - // var h = Height; - // var maxw = MaxWidth; - // var maxh = MaxHeight; - // var minw = MinWidth; - // var minh = MinHeight; - // var margin = new Thickness( - // l.GetActualValue(finalRect.Width), - // t.GetActualValue(finalRect.Height), - // r.GetActualValue(finalRect.Width), - // b.GetActualValue(finalRect.Height)); - // //var originX = finalRect.X + margin.Left; - // //var originY = finalRect.Y + margin.Top; - // //var availableSizeMinusMargins = new Size( - // // Math.Max(0, finalRect.Width - margin.Left - margin.Right), - // // Math.Max(0, finalRect.Height - margin.Top - margin.Bottom)); - - // //var size = availableSizeMinusMargins; - // var scale = Root.Scaling; - - // //if (Name == "2号") - // //{ - - // //} - - // var size = DesiredSize.Deflate(margin); - // if (!l.IsAuto && !r.IsAuto) - // { - // size.Width = Math.Max(finalRect.Width - l.GetActualValue(finalRect.Width) - r.GetActualValue(finalRect.Width), 0); - // } - // if (!t.IsAuto && !b.IsAuto) - // { - // size.Height = Math.Max(finalRect.Height - t.GetActualValue(finalRect.Height) - b.GetActualValue(finalRect.Height), 0); - // } - // if (!w.IsAuto) - // { - // size.Width = Math.Max(0, w.GetActualValue(finalRect.Width)); - // } - // if (!h.IsAuto) - // { - // size.Height = Math.Max(0, h.GetActualValue(finalRect.Height)); - // } - // if (!minw.IsAuto) - // { - // size.Width = Math.Max(size.Width, minw.GetActualValue(finalRect.Width)); - // } - // if (!minh.IsAuto) - // { - // size.Height = Math.Max(size.Height, minh.GetActualValue(finalRect.Height)); - // } - // if (!maxw.IsAuto) - // { - // size.Width = Math.Min(size.Width, maxw.GetActualValue(finalRect.Width)); - // } - // if (!maxh.IsAuto) - // { - // size.Height = Math.Min(size.Height, maxh.GetActualValue(finalRect.Height)); - // } - - // //var s = _previousArrangeResultSize; - // //if (_previousArrangeFinalSize != size) - // //{ - // var s = ArrangeOverride(size); - // // _previousArrangeResultSize = s; - // // _previousArrangeFinalSize = size; - // //} - - // size = new Size(Math.Max(s.Width, size.Width), Math.Max(s.Height, size.Height)); - - // if (!minw.IsAuto) - // { - // size.Width = Math.Max(size.Width, minw.GetActualValue(finalRect.Width)); - // } - // if (!minh.IsAuto) - // { - // size.Height = Math.Max(size.Height, minh.GetActualValue(finalRect.Height)); - // } - // if (!maxw.IsAuto) - // { - // size.Width = Math.Min(size.Width, maxw.GetActualValue(finalRect.Width)); - // } - // if (!maxh.IsAuto) - // { - // size.Height = Math.Min(size.Height, maxh.GetActualValue(finalRect.Height)); - // } - - - // var originX = finalRect.X + l.GetActualValue(finalRect.Width); - // var originY = finalRect.Y + t.GetActualValue(finalRect.Height); - // if (l.IsAuto && !r.IsAuto) - // { - // originX = finalRect.Right - size.Width - r.GetActualValue(finalRect.Width); - // } - // else if (l.IsAuto && r.IsAuto) - // { - // originX = finalRect.Left + (finalRect.Width - size.Width) / 2; - // } - // if (t.IsAuto && !b.IsAuto) - // { - // originY = finalRect.Bottom - size.Height - b.GetActualValue(finalRect.Height); - // } - // else if (t.IsAuto && b.IsAuto) - // { - // originY = finalRect.Top + (finalRect.Height - size.Height) / 2; - // } - // if (UseLayoutRounding) - // { - // originX = (float)Math.Floor(originX * scale) / scale; - // originY = (float)Math.Floor(originY * scale) / scale; - // size.Width = (float)Math.Ceiling(size.Width * scale) / scale; - // size.Height = (float)Math.Ceiling(size.Height * scale) / scale; - // } - - // //var previousSize = ActualSize; - // //var previousOffset = VisualOffset; - // //var bounds = GetHostClipBounds(new Rect(new Point(), previousSize)); - // //if (previousSize != size || previousOffset != new Point(originX, originY)) - // //{ - // var offset = new Point(originX, originY); - // VisualOffset = offset; - // ActualSize = size; - // // if (children != null) - // // { - // // foreach (UIElement item in children) - // // { - // // var rect = item.previousRenderRect; - // // rect.Union(item.RenderBounds); - // // bounds.Union(rect); - // // //Host.Invalidate(rect); - // // } - // // } - // // bounds.Union(GetHostClipBounds(new Rect(new Point(), size))); - // // Host.Invalidate(bounds); - // //} - - // //var p = Parent; - // //if (p != null) - // //{ - // // p.Invalidate(); - // //} - //} - /// - /// Positions child elements as part of a layout pass. - /// - /// The size available to the control. - /// The actual size used. - protected virtual Size ArrangeOverride(in Size finalSize) - { - var rect = new Rect(0, 0, finalSize.Width, finalSize.Height); - foreach (UIElement child in Children) - { - child.Arrange(rect); - } - - return finalSize; - } - ///// - ///// 去掉Padding - ///// - ///// - ///// - //protected Rect GetArrangeRect(Size finalSize) - //{ - // //var rect = new Rect(finalSize); - // return new Rect(0, 0, finalSize.Width, finalSize.Height); - //} - - /// - /// Invalidates the measurement of the control and queues a new layout pass.测量 - /// - public void InvalidateMeasure() - { - if (IsMeasureValid && !IsDisposed) - { - //Logger.Verbose(LogArea.Layout, this, "Invalidated measure"); - - IsMeasureValid = false; - IsArrangeValid = false; - Root?.InvalidateMeasure(this); - } - } - /// - /// Invalidates the arrangement of the control and queues a new layout pass.布局 - /// - public void InvalidateArrange() - { - if (IsArrangeValid && !IsDisposed) - { - IsArrangeValid = false; - //LayoutManager.Instance?.InvalidateArrange(this); - Root?.InvalidateArrange(this); - //var parent = Parent; - //if (parent != null) - //{ - // parent.Invalidate(); - //} - } - } - - /// - /// Tests whether any of a 's properties incude nagative values, - /// a NaN or Infinity. - /// - /// The rect. - /// True if the rect is invalid; otherwise false. - private static bool IsInvalidRect(Rect rect) - { - return rect.Width < 0 || rect.Height < 0 || - float.IsInfinity(rect.X) || float.IsInfinity(rect.Y) || - float.IsInfinity(rect.Width) || float.IsInfinity(rect.Height) || - float.IsNaN(rect.X) || float.IsNaN(rect.Y) || - float.IsNaN(rect.Width) || float.IsNaN(rect.Height); - } - - /// - /// 坐标转换,将父级坐标通过逆向变换为自己内部坐标 - /// - /// - /// - public virtual Point TransformPointInvert(Point point) - { - Matrix m = VisualTransform.Value; - var op = RenderTransformOrigin; - Rect rect = GetContentBounds(); - Point p = new Point(point.X - op.X.GetActualValue(rect.Width) - rect.X, point.Y - op.Y.GetActualValue(rect.Height) - rect.Y); - m.TranslatePrepend(-rect.X, -rect.Y); - m.Invert(); - m.Translate(op.X.GetActualValue(rect.Width), op.Y.GetActualValue(rect.Height)); - return m.Transform(p); - } - /// - /// 坐标转换,将自己内部坐标转换成父级坐标 - /// - /// - /// - public virtual Point TransformPoint(Point point) - { - Rect rect = this.GetContentBounds(); - Matrix m = Matrix.Identity; - var op = this.RenderTransformOrigin; - m.TranslatePrepend(rect.X + op.X.GetActualValue(rect.Width), rect.Y + op.Y.GetActualValue(rect.Height)); - m.Prepend(this.VisualTransform.Value); - m.TranslatePrepend(-op.X.GetActualValue(rect.Width), -op.Y.GetActualValue(rect.Height)); - return m.Transform(point); - } - - private Point TransformPoint(in Point point, in Rect rect, in PointField op) - { - Matrix m = Matrix.Identity; - m.TranslatePrepend(rect.X + op.X.GetActualValue(rect.Width), rect.Y + op.Y.GetActualValue(rect.Height)); - m.Prepend(this.VisualTransform.Value); - m.TranslatePrepend(-op.X.GetActualValue(rect.Width), -op.Y.GetActualValue(rect.Height)); - return m.Transform(point); - } - /// - /// 用自己的内部坐标测试内部元素,从最深的后代元素到根(自己) - /// - /// - /// - public IEnumerable HitTest(Point point) - { - List list = new List(); - if (HitTest(point, this, list)) - { - list.Add(this); - } - else - { - if (HitTestCore(new Point(point.X + ActualOffset.X, point.Y + ActualOffset.Y))) - { - list.Add(this); - } - } - return list; - } - - bool HitTest(Point point, UIElement element, List list) - { - bool isHit = false; - for (int i = element.Children.Count - 1; i >= 0; i--) - { - var item = element.Children[i]; - if (item.Visibility != Visibility.Collapsed) - { - Point l = item.ActualOffset; - Point r = item.TransformPointInvert(point); - Point t = new Point(r.X - l.X, r.Y - l.Y); - - isHit = item.HitTestCore(r); - if (item.ClipToBounds)//如果是裁剪了,需要先判断自己,再判断子元素 - { - if (isHit) - { - HitTest(t, item, list); - } - } - else - { - isHit = (HitTest(t, item, list) || isHit); - } - if (isHit) - { - list.Add(item); - } - } - } - return isHit; - } - - - public override void Render(DrawingContext dc) - { - base.Render(dc); - if (Site != null) - { - if (Site.GetType().GetProperty("ShowBorder") == null || (bool)Site.GetPropretyValue("ShowBorder")) - { - var s = ActualSize; - s.Width = Math.Max(1, s.Width); - s.Height = Math.Max(1, s.Height); - ViewFill fill = Color.FromRgb(80, 80, 80); - using (var sb = fill.CreateBrush(new Rect(0, 0, s.Width, s.Height), Root.RenderScaling)) - { - var dpi = Root.RenderScaling; - var str = new Stroke(1); - str.DashStyle = DashStyles.Dash; - str.Width = Math.Max(0.1f, (float)Math.Round(dpi * str.Width) / dpi); - dc.DrawRectangle(sb, str, new Rect(str.Width / 2, str.Width / 2, s.Width - str.Width, s.Height - str.Width)); - } - } - } - var fm = FocusMethod; - if (fm == NavigationMethod.Directional || fm == NavigationMethod.Tab) - { - var s = ActualSize; - var f = FocusFrameFill; - var padding = FocusFramePadding; - if (s.Width > padding.Horizontal && s.Height > padding.Vertical && f != null) - { - using (var sb = f.CreateBrush(new Rect(0, 0, s.Width, s.Height), Root.RenderScaling)) - { - var dpi = Root.RenderScaling; - var str = FocusFrameStroke; - str.Width = (float)Math.Round(dpi * str.Width) / dpi; - dc.DrawRectangle(sb, str, new Rect(padding.Left, padding.Top, s.Width - padding.Horizontal, s.Height - padding.Vertical)); - } - } - } - } - /// - /// 获取相对于父级的正矩形剪辑区域 - /// - /// - public Rect GetClipBounds() - { - Rect r = GetContentBounds(); - if (VisualTransform == Transform.Identity) - { - return r; - } - Point lt = new Point(); - Point tr = new Point(r.Width, 0); - Point lb = new Point(0, r.Height); - Point rb = new Point(r.Width, r.Height); - var op = RenderTransformOrigin; - //Rect r = GetContentBounds(); - lt = TransformPoint(lt, r, op); - tr = TransformPoint(tr, r, op); - lb = TransformPoint(lb, r, op); - rb = TransformPoint(rb, r, op); - - float minX = Math.Min(Math.Min(Math.Min(lt.X, tr.X), lb.X), rb.X); - float minY = Math.Min(Math.Min(Math.Min(lt.Y, tr.Y), lb.Y), rb.Y); - float maxX = Math.Max(Math.Max(Math.Max(lt.X, tr.X), lb.X), rb.X); - float maxY = Math.Max(Math.Max(Math.Max(lt.Y, tr.Y), lb.Y), rb.Y); - return new Rect(minX, minY, maxX - minX, maxY - minY); - } - /// - /// 获取内部相对于父级的正矩形剪辑区域 - /// - /// - public Rect GetClipBounds(in Rect rect) - { - Rect r = GetContentBounds(); - if (VisualTransform == Transform.Identity) - { - return new Rect(r.X + rect.X, rect.Y + r.Y, rect.Width, rect.Height); - } - Point lt = new Point(rect.Left, rect.Top); - Point tr = new Point(rect.Left + rect.Width, rect.Top); - Point lb = new Point(rect.Left, rect.Top + rect.Height); - Point rb = new Point(rect.Left + rect.Width, rect.Top + rect.Height); - var op = RenderTransformOrigin; - lt = TransformPoint(lt, r, op); - tr = TransformPoint(tr, r, op); - lb = TransformPoint(lb, r, op); - rb = TransformPoint(rb, r, op); - - float minX = Math.Min(Math.Min(Math.Min(lt.X, tr.X), lb.X), rb.X); - float minY = Math.Min(Math.Min(Math.Min(lt.Y, tr.Y), lb.Y), rb.Y); - float maxX = Math.Max(Math.Max(Math.Max(lt.X, tr.X), lb.X), rb.X); - float maxY = Math.Max(Math.Max(Math.Max(lt.Y, tr.Y), lb.Y), rb.Y); - return new Rect(minX, minY, maxX - minX, maxY - minY); - } - - public override Rect GetContentBounds() - { - if (IsRoot) - { - //Size s = Root.Size; - return new Rect(new Point(), Root.ActualSize); - } - //return new Rect(VisualOffset, new Size(Width, Height)); - return contentBounds; - //return new Rect(VisualOffset, ActualSize); - } - //private float GetLayoutScale() - //{ - // return Root.Scaling; - //} - - //bool drawFocusRect = false; - //private bool DrawFocusRect - //{ - // get { return drawFocusRect; } - // set - // { - // if (drawFocusRect != value) - // { - // drawFocusRect = value; - // Invalidate(); - // } - // } - //} - public void Invoke(Action action) - { - if (!this.IsDisposed) - { - Threading.Dispatcher.MainThread.Invoke(action); - } - } - - public void BeginInvoke(Action action) - { - if (!this.IsDisposed) - { - Threading.Dispatcher.MainThread.BeginInvoke(action); - } - } - - public bool Focus(NavigationMethod m) - { - FocusMethod = m; - IsFocused = true; - //System.Diagnostics.Debug.WriteLine(this); - var host = Root; - if (Visibility != Visibility.Visible || !IsEnabled || host == null || !host.CanActivate) - { - return false; - } - - host.InputManager.KeyboardDevice.SetFocus(this); - IsKeyboardFocused = true; - IsKeyboardFocusWithin = true; - //if (m == NavigationMethod.Tab || m == NavigationMethod.Directional) - //{ - //} - var e = new GotFocusEventArgs(this) { NavigationMethod = m }; - OnGotFocus(e); - InnerFocus(e); - return true; - } - public bool Focus() - { - return Focus(NavigationMethod.Unspecified); - } - - private void InnerFocus(GotFocusEventArgs e) - { - if (e.OriginalSource != this) - { - IsKeyboardFocusWithin = true; - IsKeyboardFocused = false; - IsFocused = false; - OnGotFocus(e); - } - //else - //{ - // IsFocused = true; - // IsKeyboardFocused = true; - //} - var p = Parent; - if (p != null) - { - if (!e.Handled) - { - p.InnerFocus(e); - } - foreach (UIElement item in p.Children) - { - if (item != this) - {//同级的其他元素失去焦点 - item.InnerLostFocus(); - } - } - } - } - - internal void InnerLostFocus() - { - if (!IsDisposed && IsKeyboardFocusWithin) - { - IsKeyboardFocused = false; - IsKeyboardFocusWithin = false; - IsFocused = false; - FocusMethod = null; - OnLostFocus(new RoutedEventArgs(this)); - foreach (UIElement item in Children) - {//子元素都失去焦点 - item.InnerLostFocus(); - } - } - } - - UIElementCollection children; - /// - /// 子级,一般自定义组件的时候使用 - /// - [NotCpfProperty] - internal protected virtual UIElementCollection Children - { - get - { - if (children == null) - { - children = new UIElementCollection(this); - } - return children; - } - } - /// - /// 获取子元素 - /// - /// - -#if Net4 - public IList GetChildren() -#else - public IReadOnlyList GetChildren() -#endif - { - return Children; - } - /// - /// 当添加触发器时并且触发器有设置动画,如果满足条件是否播放动画 - /// - [Description("当添加触发器时并且触发器有设置动画,如果满足条件是否播放动画")] - public bool PlayAnimationOnAddTrigger - { - get { return GetValue(); } - set { SetValue(value); } - } - - internal Triggers triggers; - /// - /// 触发器集合 - /// - [NotCpfProperty] - [Category("设计")] - [Description("设置触发器")] - public Triggers Triggers - { - get - { - if (triggers == null) - { - triggers = new Triggers(); - triggers.CollectionChanged += (s, e) => - { - Trigger n = e.NewItem; - var o = e.OldItem; - switch (e.Action) - { - case CollectionChangedAction.Add: - if (!string.IsNullOrEmpty(n.Property) && n.Condition(this)) - { - if (n.TargetRelation != null && n.TargetRelation != Relation.Me) - { - foreach (var item in n.TargetRelation.Query(this)) - { - SetTrigger(n, item, true, true); - } - } - else - { - SetTrigger(n, this, true, true); - } - } - break; - case CollectionChangedAction.Remove: - //foreach (var setter in e.Item.Setters) - //{ - // ClearTriggerValue(e.Item, setter.Key); - //} - if (o.TargetRelation != null && o.TargetRelation != Relation.Me) - { - foreach (var item in o.TargetRelation.Query(this)) - { - SetTrigger(o, item, false); - } - } - else - { - SetTrigger(o, this, false); - } - break; - case CollectionChangedAction.Replace: - if (!string.IsNullOrEmpty(n.Property) && n.Condition(this)) - { - if (n.TargetRelation != null && n.TargetRelation != Relation.Me) - { - foreach (var item in n.TargetRelation.Query(this)) - { - SetTrigger(n, item, true, true); - } - } - else - { - SetTrigger(n, this, true, true); - } - } - if (o.TargetRelation != null && o.TargetRelation != Relation.Me) - { - foreach (var item in o.TargetRelation.Query(this)) - { - SetTrigger(o, item, false); - } - } - else - { - SetTrigger(o, this, false); - } - break; - } - }; - } - return triggers; - } - } - - [NotCpfProperty] - [Browsable(false)] - public ISite Site - { - get; - set; - } - /// - /// 是否处在设计模式 - /// - [UIPropertyMetadata(false, true)] - [Browsable(false)] - public bool DesignMode - { - get - { - return (bool)GetValue(); - } - } - /// - /// 是否是设计模式下的根元素 - /// - [Browsable(false)] - public bool IsRootInDesignMode - { - get - { - return (bool)GetValue(); - } - } - - /// - /// 将指定工作区点的位置计算成屏幕坐标。像素坐标 - /// - /// - /// - public override Point PointToScreen(Point point) - { - var p = this; - while (p != null) - { - point = p.TransformPoint(point); - p = p.Parent; - } - point = Root.PointToScreen(point); - return point; - } - /// - /// 将指定工作区点的位置计算成相对View的位置 - /// - /// - /// - public Point PointToView(Point point) - { - var p = this; - while (p != null) - { - point = p.TransformPoint(point); - p = p.Parent; - } - return point; - } - /// - /// 将指定屏幕点的像素位置计算成工作区坐标。 - /// - /// - /// - public Point PointToClient(Point point) - { - point = Root.ViewImpl.PointToClient(point); - var p = this; - List list = new List(); - while (p != null) - { - list.Add(p); - p = p.Parent; - } - for (int i = list.Count - 1; i >= 0; i--) - { - var item = list[i]; - Point l = new Point(); - if (!item.IsRoot) - { - l = item.ActualOffset; - } - Point r = item.TransformPointInvert(point); - point = new Point(r.X - l.X, r.Y - l.Y); - } - return point; - } - - /// - /// 应用到元素上的类名,多个类用,分割 - /// - [Description("应用到元素上的类名,多个类用,分割")] - [Category("设计")] - [NotCpfProperty] - public Classes Classes - { - get - { - if (classes == null) - { - classes = new Classes(); - } - return classes; - } - set - { - classes = value; - } - } - - //Styles styles; - - protected override void Dispose(bool disposing) - { - if (disposing) - { - PresenterFor = null; - if (toolTipElement) - { - toolTipElement.Dispose(); - } - if (triggers != null) - { - triggers.Clear(); - } - var p = Parent; - if (p != null) - { - p.children.Remove(this); - } - if (notifyList != null) - { - foreach (var item in notifyList) - { - item.Key.PropertyChanged -= Notify_PropertyChanged; - } - } - if (children != null) - { - var c = children.Count; - //for (int i = 0; i < c; i++) - //{ - // var cc = children[0]; - // cc.Dispose(); - //} - for (int i = c - 1; i >= 0; i--) - { - children[i].Dispose(); - } - } - } - this.RaiseEvent(EventArgs.Empty, nameof(Disposed)); - base.Dispose(disposing); - } - - - /// - /// 查询所有内部元素,包含所有层 - /// - /// - /// - public IEnumerable Find() where T : UIElement - { - if (children == null) - { - yield break; - } - foreach (UIElement item in Children) - { - if (item is T) - { - yield return (T)item; - } - foreach (var c in item.Find()) - { - yield return c; - } - } - } - - internal void LoadStyle() - { - var host = Root; - //if (host.StyleSheet != null) - //{ - // foreach (var item in host.StyleSheet.StyleRules) - // { - // //host.SetStyle(this, item); - // } - //} - if (host.Styles.Count > 0) - { - host.Styles.Update(); - host.SetStyle(this); - } - } - [NotCpfProperty] - internal bool loadStyle { set { SetFlag(CoreFlags.loadStyle, value); } get { return GetFlag(CoreFlags.loadStyle); } }// = true; - void AttachedToVisualTree() - { - if (loadStyle) - { - Root.OnElementInitialize(this); - } - var host = Root; - if (bindings != null) - { - foreach (var item in bindings.binds) - { - foreach (var binding in item.Value) - { - if (binding.SourceElementLayer.HasValue) - { - UIElement obj = this; - for (int i = 1; i < binding.SourceElementLayer.Value + 1; i++) - { - obj = obj.Parent; - } - if (binding.Source == null) - { - binding.Source = new WeakReference(obj); - } - var bindingMode = binding.BindingMode; - if (bindingMode == BindingMode.OneWay || bindingMode == BindingMode.TwoWay) - { - //((INotifyPropertyChanged)obj).PropertyChanged += binding.PropertyChanged; - binding.RegisterPropertyChanged((INotifyPropertyChanged)obj); - binding.SourceToTarget(); - } - else if (bindingMode == BindingMode.OneWayToSource) - { - binding.TargetToSource(); - } - else if (bindingMode == BindingMode.OneTime) - { - binding.SourceToTarget(); - } - } - } - } - } - if (inheritsPropertyName != null) - { - foreach (var item in inheritsPropertyName) - { - if (!HasLocalOrStyleValue(item, out var attribute)) - { - var p = Parent; - while (p != null) - { - if (p.inheritsPropertyName != null) - { - if (p.inheritsPropertyName.Contains(item)) - { - if (p.inheritsValues.TryGetValue(item, out InheritsValue v)) - { - var old = GetValue(item); - inheritsValues.Remove(item); - inheritsValues.Add(item, v); - if (!old.Equal(v.Value)) - { - //OnPropertyChanged(item, old, v.Value, GetPropertyMetadata(item)); - OnPropertyChanged(item, old, v.Value, attribute); - } - break; - } - else if (p.HasLocalOrStyleValue(item, out _)) - { - var value = p.GetValue(item); - var old = GetValue(item); - inheritsValues.Remove(item); - v = new InheritsValue { Value = value, ValueForm = ValueForm.Property }; - inheritsValues.Add(item, v); - if (!old.Equal(v.Value)) - { - //OnPropertyChanged(item, old, v.Value, GetPropertyMetadata(item)); - OnPropertyChanged(item, old, v.Value, attribute); - } - break; - } - } - } - p = p.Parent; - } - } - } - } - - - if (children != null) - { - foreach (UIElement item in children) - { - item.Root = host; - item.AttachedToVisualTree(); - } - } - OnAttachedToVisualTree(); - } - - /// - /// Called when the control is added to a visual tree. - /// - protected virtual void OnAttachedToVisualTree() - { - - } - - /// - /// Called when the control is removed from a visual tree. - /// - protected virtual void OnDetachedFromVisualTree() - { - //if (this is Control control && control.IsInitialized) - //{ - // Root.OnElementFinalize(this); - //} - //else - //{ - // Root.OnElementFinalize(this); - //} - if (toolTipElement) - { - if (ToolTipUIElement == toolTipElement) - { - ToolTipHost.Visibility = Visibility.Collapsed; - ToolTipUIElement = null; - } - } - if (inheritsPropertyName != null) - { - foreach (var item in inheritsValues.ToArray()) - { - if (!HasLocalOrStyleValue(item.Key, out var attribute)) - { - var old = GetValue(item.Key); - //if (inheritsValues.ContainsKey(item)) - //{ - inheritsValues.Remove(item.Key); - //} - var v = GetValue(item.Key); - if (!old.Equal(v)) - { - //OnPropertyChanged(item.Key, old, v, GetPropertyMetadata(item.Key)); - OnPropertyChanged(item.Key, old, v, attribute); - } - } - } - //inheritsValues.Clear(); - } - //var name = Name; - //if (!string.IsNullOrWhiteSpace(name)) - //{ - // var r = Root; - // if (r.nameDic.TryGetValue(name, out UIElement e)) - // { - // if (e == this) - // { - // r.nameDic.Remove(name); - // } - // } - //} - IsArrangeValid = false; - if (children != null) - { - foreach (UIElement item in children) - { - item.OnDetachedFromVisualTree(); - item.Root = null; - } - } - if (triggers != null) - { - foreach (var item in triggers.Where(a => a.Style != null).ToArray()) - { - triggers.Remove(item); - } - } - if (bindings != null) - { - foreach (var item in bindings.binds) - { - foreach (var binding in item.Value) - { - if (binding.SourceElementLayer.HasValue && binding.Source != null && binding.Source.IsAlive) - { - //((INotifyPropertyChanged)binding.Source.Target).PropertyChanged -= binding.PropertyChanged; - binding.CancellationPropertyChanged((INotifyPropertyChanged)binding.Source.Target); - binding.Source = null; - } - } - } - } - ClearStyleValues(); - //if (commands != null) - //{ - // foreach (var item in commands.commands) - // { - // foreach (var command in item.Value) - // { - // if (command.SourceElementLayer.HasValue) - // { - // command.Target = null; - // } - // } - // } - //} - } - - internal void RaiseUIElementAdded(UIElement child) - { - //if (child.ZIndex != 0) - //{ - // //needSortZIndex = true; - // children.InvalidateZIndex(); - //} - if (child.IsRoot) - { - throw new Exception("根元素不能作为子元素嵌套"); - } - child.Root = Root; - if (Root != null) - { - child.IsMeasureValid = false; - child.AttachedToVisualTree(); - } - viewRenderRect = true; - InvalidateMeasure(); - OnUIElementAdded(new UIElementAddedEventArgs(child, this)); - } - - protected virtual void OnUIElementAdded(UIElementAddedEventArgs e) - { - this.RaiseEvent(e, "UIElementAdded"); - } - //public static readonly RoutedEvent EventUIElementAdded = new RoutedEvent("UIElementAdded", UIElementType, typeof(EventHandler)); - /// - /// 添加可视化对象的时候 - /// - public virtual event EventHandler UIElementAdded - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - internal void RaiseUIElementRemoved(UIElement child) - { - if (child.Root != null) - { - child.OnDetachedFromVisualTree(); - child.Root = null; - } - - if (!IsDisposed) - { - viewRenderRect = true; - InvalidateMeasure(); - } - OnUIElementRemoved(new UIElementRemovedEventArgs(child, this)); - if (child.needDispose) - { - child.Dispose(); - } - } - protected virtual void OnUIElementRemoved(UIElementRemovedEventArgs e) - { - this.RaiseEvent(e, "UIElementRemoved"); - } - //public static readonly RoutedEvent EventUIElementRemoved = new RoutedEvent("UIElementRemoved", UIElementType, typeof(EventHandler)); - /// - /// 移除可视化对象的时候 - /// - public virtual event EventHandler UIElementRemoved - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - public virtual event EventHandler DesiredSizeChanged - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - protected virtual void OnPreviewMouseDown(MouseButtonEventArgs e) - { - //System.Diagnostics.Debug.WriteLine("OnPreviewMouseDown" + this); - this.RaiseEvent(e, nameof(PreviewMouseDown)); - } - - public virtual event EventHandler PreviewMouseDown - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnPreviewMouseUp(MouseButtonEventArgs e) - { - //System.Diagnostics.Debug.WriteLine("OnPreviewMouseUp" + this + e.OriginalSource); - this.RaiseEvent(e, nameof(PreviewMouseUp)); - } - - public virtual event EventHandler PreviewMouseUp - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnMouseDown(MouseButtonEventArgs e) - { - //if (e.MouseButton == MouseButton.Left) - //{ - // IsMouseLeftButtonDown = true; - //} - //System.Diagnostics.Debug.WriteLine(e.OriginalSource); - this.RaiseEvent(e, nameof(MouseDown)); - } - - public virtual event EventHandler MouseDown - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - protected virtual void OnMouseUp(MouseButtonEventArgs e) - { - //if (e.MouseButton == MouseButton.Left) - //{ - // IsMouseLeftButtonDown = false; - //} - this.RaiseEvent(e, nameof(MouseUp)); - if (e.MouseButton == MouseButton.Right && !e.Handled) - { - var cm = ContextMenu; - if (cm != null) - { - cm.DataContext = DataContext; - cm.CommandContext = CommandContext; - cm.PlacementTarget = this; - cm.IsOpen = true; - } - } - } - //public static readonly RoutedEvent MouseUpEvent = new RoutedEvent("MouseUp", UIElementType, MouseEventType); - public virtual event EventHandler MouseUp - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnDoubleClick(RoutedEventArgs e) - { - this.RaiseEvent(e, nameof(DoubleClick)); - } - - public virtual event EventHandler DoubleClick - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnMouseMove(MouseEventArgs e) - { - if (e.OriginalSource == this) - { - Root.SetCursor(Cursor); - } - this.RaiseEvent(e, nameof(MouseMove)); - } - //public static readonly RoutedEvent MouseMoveEvent = new RoutedEvent("MouseMove", UIElementType, MouseEventType); - public virtual event EventHandler MouseMove - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnMouseEnter(MouseEventArgs e) - { - if (toolTipElement) - { - var re = new RoutedEventArgs(this); - RaiseEvent(re, nameof(ToolTipOpening)); - if (!re.Handled) - { - ToolTipHost.Width = FloatField.Auto; - ToolTipHost.Height = FloatField.Auto; - ShowTip(Root, toolTipElement); - } - } - IsMouseOver = true; - this.RaiseEvent(e, nameof(MouseEnter)); - } - //public static readonly RoutedEvent MouseEnterEvent = new RoutedEvent("MouseEnter", UIElementType, MouseEventType); - public virtual event EventHandler MouseEnter - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnMouseLeave(MouseEventArgs e) - { - if (toolTipElement) - { - if (ToolTipUIElement == toolTipElement) - { - ToolTipHost.Visibility = Visibility.Collapsed; - ToolTipUIElement = null; - } - } - IsMouseOver = false; - this.RaiseEvent(e, nameof(MouseLeave)); - } - //public static readonly RoutedEvent MouseLeaveEvent = new RoutedEvent("MouseLeave", UIElementType, MouseEventType); - public virtual event EventHandler MouseLeave - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnMouseWheel(MouseWheelEventArgs e) - { - this.RaiseEvent(e, nameof(MouseWheel)); - } - //public static readonly RoutedEvent MouseWheelEvent = new RoutedEvent("MouseWheel", UIElementType, MouseEventType); - public virtual event EventHandler MouseWheel - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnKeyDown(KeyEventArgs e) - { - this.RaiseEvent(e, nameof(KeyDown)); - } - //public static Type KeyEventType = typeof(EventHandler); - //public static readonly RoutedEvent KeyDownEvent = new RoutedEvent("KeyDown", UIElementType, KeyEventType); - public virtual event EventHandler KeyDown - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnKeyUp(KeyEventArgs e) - { - this.RaiseEvent(e, nameof(KeyUp)); - } - //public static readonly RoutedEvent KeyUpEvent = new RoutedEvent("KeyUp", UIElementType, KeyEventType); - public virtual event EventHandler KeyUp - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - protected virtual void OnTextInput(TextInputEventArgs e) - { - this.RaiseEvent(e, nameof(TextInput)); - } - public virtual event EventHandler TextInput - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - protected virtual void OnGotFocus(GotFocusEventArgs e) - { - this.RaiseEvent(e, nameof(GotFocus)); - } - //public static readonly RoutedEvent GotFocusEvent = new RoutedEvent("GotFocus", UIElementType, typeof(EventHandler)); - public virtual event EventHandler GotFocus - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnLostFocus(RoutedEventArgs e) - { - RaiseEvent(e, nameof(LostFocus)); - } - //public static readonly RoutedEvent LostFocusEvent = new RoutedEvent("LostFocus", UIElementType, typeof(EventHandler)); - public virtual event EventHandler LostFocus - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - - protected virtual void OnLayoutUpdated() - { - this.RaiseEvent(new RoutedEventArgs(this), nameof(LayoutUpdated)); - } - /// - /// 捕获鼠标,只有鼠标在元素范围内按下,而且IsEnabled为TRUE的时候才能捕获。当对象已捕获鼠标后,它接收鼠标输入,不论鼠标指针是否在其边界区域。 通常只有在执行模拟拖动操作时才捕获鼠标。 若要释放鼠标捕获,请对具有捕获的对象调用 ReleaseMouseCapture 方法。 - /// - /// - public bool CaptureMouse() - { - var host = Root; - if (IsEnabled && host != null) - { - host.InputManager.MouseDevice.Capture(this); - IsMouseCaptured = true; - OnCaptureMouse(); - return true; - } - return false; - } - - protected virtual void OnCaptureMouse() - { - - } - - /// - /// ReleaseMouseCapture 方法对于已通过使用 CaptureMouse 方法捕获鼠标的对象禁用鼠标捕获。 当对象已捕获鼠标后,它接收鼠标输入,不论鼠标指针是否在其边界区域。 对不具有鼠标捕获的对象调用 ReleaseMouseCapture 无效。 - /// - public void ReleaseMouseCapture() - { - var host = Root; - if (host != null) - { - host.InputManager.MouseDevice.Capture(null); - } - SetReleaseMouseCapture(); - } - - internal void SetReleaseMouseCapture() - { - if (IsMouseCaptured) - { - IsMouseCaptured = false; - OnReleaseMouseCapture(); - } - } - - protected virtual void OnReleaseMouseCapture() - { - - } - - //public static readonly RoutedEvent LayoutUpdatedEvent = new RoutedEvent("LayoutUpdated", UIElementType, typeof(EventHandler)); - public virtual event EventHandler LayoutUpdated - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - public event EventHandler Disposed - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - //public event EventHandler ToolTipClosing - //{ - // add { AddHandler(value); } - // remove { RemoveHandler(value); } - //} - public event EventHandler ToolTipOpening - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnDragEnter(DragEventArgs e) - { - IsDragOver = true; - //System.Diagnostics.Debug.WriteLine(this + " " + e.DragEffects); - RaiseEvent(e, nameof(DragEnter)); - } - public event EventHandler DragEnter - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnDragLeave(EventArgs e) - { - IsDragOver = false; - RaiseEvent(e, nameof(DragLeave)); - } - public event EventHandler DragLeave - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnDragOver(DragEventArgs e) - { - RaiseEvent(e, nameof(DragOver)); - } - public event EventHandler DragOver - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - protected virtual void OnDrop(DragEventArgs e) - { - RaiseEvent(e, nameof(Drop)); - } - public event EventHandler Drop - { - add { AddHandler(value); } - remove { RemoveHandler(value); } - } - - public override string ToString() - { - if (!string.IsNullOrEmpty(Name)) - { - return "#" + Name; - } - return base.ToString(); - } - /// - /// 克隆依赖属性,绑定,子元素,触发器 - /// - /// - public override object Clone() - { - var e = base.Clone() as UIElement; - if (children != null && children.Count > 0) - { - foreach (UIElement item in children) - { - e.Children.Add(item.Clone() as UIElement); - } - } - if (triggers != null && triggers.Count > 0) - { - foreach (Trigger item in triggers) - { - e.Triggers.Add(item); - } - } - if (inheritsValues != null) - { - foreach (var item in inheritsValues) - { - if (HasLocalOrStyleValue(item.Key, out _)) - { - e.inheritsValues.Add(item.Key, item.Value); - } - } - } - return e; - } - /// - /// 将依赖属性本地值,绑定,子元素,触发器,拷贝到另外个对象 - /// - /// - public void CopyTo(UIElement element) - { - base.CopyTo(element); - if (children != null && children.Count > 0) - { - element.Children.Clear(); - foreach (UIElement item in children) - { - element.Children.Add(item.Clone() as UIElement); - } - } - if (triggers != null && triggers.Count > 0) - { - element.Triggers.Clear(); - foreach (Trigger item in triggers) - { - element.Triggers.Add(item); - } - } - } - - //public IEnumerator GetEnumerator() - //{ - // return Children.GetEnumerator(); - //} - - //IEnumerator IEnumerable.GetEnumerator() - //{ - // return Children.GetEnumerator(); - //} - //public static UIElement Parse(string str) - //{ - // return null; - //} - - ///// - ///// 字符串解析为UI元素 - ///// - ///// - //public static implicit operator UIElement(string n) - //{ - // return Parse(n); - //} - - IntPtr id; - /// - /// 获取对象唯一地址 - /// - /// - public IntPtr GetIntPtr() - { - if (id == IntPtr.Zero) - { - GCHandle h = GCHandle.Alloc(this, GCHandleType.WeakTrackResurrection); - id = GCHandle.ToIntPtr(h); - } - return id; - } - [NotCpfProperty] - internal bool needDispose - { - get { return GetFlag(CoreFlags.needDispose); } - set { SetFlag(CoreFlags.needDispose, value); } - } - - internal bool GetFlag(CoreFlags field) - { - return (_flags & field) != 0; - } - - internal void SetFlag(CoreFlags field, bool value) - { - if (value) - { - _flags |= field; - } - else - { - _flags &= (~field); - } - } - /// - /// 用来省内存,8个bool字段只要1字节,省7个字节 - /// - private CoreFlags _flags; - } - - [Flags] - enum CoreFlags : byte - { - None = 0, - needDispose = 0b10000000, - loadStyle = 0b01000000, - viewRenderRect = 0b00100000, - transform = 0b00010000, - inheritsSet = 0b00001000, - IsArrangeValid = 0b00000100, - isMeasureValid = 0b00000010, - isRoot = 0b00000001, - } - - struct InheritsValue - { - public object Value; - public ValueForm ValueForm; - } - - enum ValueForm : byte - { - Property, - Trigger, - Style, - Animation, - } -} diff --git a/CPF/ValueTuple.cs b/CPF/ValueTuple.cs deleted file mode 100644 index 91581ba..0000000 --- a/CPF/ValueTuple.cs +++ /dev/null @@ -1,24 +0,0 @@ -#if Net4||Net2 -namespace System -{ - /// - /// 值元组 - /// - /// - /// - [Serializable] - public struct ValueTuple - { - public ValueTuple(T1 item1, T2 item2) - { - Item1 = item1; - Item2 = item2; - } - - public T1 Item1; - - public T2 Item2; - } -} - -#endif \ No newline at end of file