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; // } //} }