gpt4 book ai didi

c# - “绑定(bind)生成器”不询问嵌套的 ICustomTypeDescriptor(路径为空)?

转载 作者:IT王子 更新时间:2023-10-29 04:45:07 25 4
gpt4 key购买 nike

我正在试验 ICustomTypeDescriptor 接口(interface)和 PropertyDescriptor 类,以便在对象上创建动态属性。我在简单对象方面取得了很大成功,但我无法获取嵌套对象来创建它们的动态属性?

例如在下面的数据绑定(bind)对话框中,我将我的 Person 类添加为 StaticResource,然后尝试对 Person.Child.Name 进行数据绑定(bind)到测试箱:

对于 Person.Child,我希望看到我动态创建的属性(NameAge),但如您所见没有按预期工作?就好像数据绑定(bind)对话框没有询问 Person.Child 上的 ICustomTypeDescriptor 接口(interface)?

关于如何使这些嵌套属性“可见”的任何指南?

外部类

public class Person : ICustomTypeDescriptor, INotifyPropertyChanged
{
private readonly List<CustomPropertyDescriptor> propertyDescriptors = new List<CustomPropertyDescriptor>();
private readonly Dictionary<string, object> properties = new Dictionary<string, object>();

public Person()
{
// 'Dynamic' Property
string name = "Name";
object value = "Person's Name";
this.properties.Add(name, value);
var propertyDescriptor = new CustomPropertyDescriptor(
typeof(Person),
name,
value,
value.GetType().GetCustomAttributes(true).Cast<Attribute>().ToArray());
this.propertyDescriptors.Add(propertyDescriptor);

// 'Dynamic' Property
name = "Child";
value = new Child();
this.properties.Add(name, value);
propertyDescriptor = new CustomPropertyDescriptor(
typeof(Child),
name,
value,
value.GetType().GetCustomAttributes(true).Cast<Attribute>().ToArray());
this.propertyDescriptors.Add(propertyDescriptor);

propertyDescriptor.PropertyChanged += this.PropertyDescriptorPropertyChanged;
}

public event PropertyChangedEventHandler PropertyChanged;

// Test Property (shouldn't be visible)
public string NotDynamic { get; set; }

public override string ToString()
{
return string.Format("{0} ({1})", this.properties["Name"], this.properties["Age"]);
}

public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}

public string GetClassName()
{
return TypeDescriptor.GetClassName(this, true);
}

public string GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}

public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}

public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}

public PropertyDescriptor GetDefaultProperty()
{
try
{
return this.propertyDescriptors.First();
}
catch (InvalidOperationException)
{
return null;
}
}

public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}

public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}

public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}

public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return new PropertyDescriptorCollection(this.propertyDescriptors.ToArray());
}

public PropertyDescriptorCollection GetProperties()
{
return this.GetProperties(null);
}

public object GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}

protected void OnPropertyChanged(string name)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}

private void PropertyDescriptorPropertyChanged(object sender, PropertyChangedEventArgs e)
{
this.OnPropertyChanged(e.PropertyName);
}
}

内部类

[TypeConverter(typeof(ExpandableObjectConverter))]
public class Child : ICustomTypeDescriptor, INotifyPropertyChanged
{
private readonly List<CustomPropertyDescriptor> propertyDescriptors = new List<CustomPropertyDescriptor>();
private readonly Dictionary<string, object> properties = new Dictionary<string, object>();

public Child()
{
// 'Dynamic' Property
string name = "Name";
object value = "Person's Child";
this.properties.Add(name, value);
var propertyDescriptor = new CustomPropertyDescriptor(
typeof(Person),
name,
value,
value.GetType().GetCustomAttributes(true).Cast<Attribute>().ToArray());
propertyDescriptor.PropertyChanged += this.PropertyDescriptorPropertyChanged;
this.propertyDescriptors.Add(propertyDescriptor);
}

public event PropertyChangedEventHandler PropertyChanged;

// Test Property (shouldn't be visible)
public string NotDynamic { get; set; }

public override string ToString()
{
return string.Format("{0} ({1})", this.properties["Name"], this.properties["Age"]);
}

public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}

public string GetClassName()
{
return TypeDescriptor.GetClassName(this, true);
}

public string GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}

public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}

public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}

public PropertyDescriptor GetDefaultProperty()
{
try
{
return this.propertyDescriptors.First();
}
catch (InvalidOperationException)
{
return null;
}
}

public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}

public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}

public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}

public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return new PropertyDescriptorCollection(this.propertyDescriptors.ToArray());
}

public PropertyDescriptorCollection GetProperties()
{
return this.GetProperties(null);
}

public object GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}

protected void OnPropertyChanged(string name)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}

private void PropertyDescriptorPropertyChanged(object sender, PropertyChangedEventArgs e)
{
this.OnPropertyChanged(e.PropertyName);
}
}

属性描述符

public class CustomPropertyDescriptor : PropertyDescriptor, INotifyPropertyChanged
{
private readonly Type componentType;
private string name;
private object value;

public CustomPropertyDescriptor(Type componentType, string name, object value, Attribute[] attributes)
: base(name, attributes)
{
this.componentType = componentType;
this.name = name;
this.value = value;
}

public event PropertyChangedEventHandler PropertyChanged;

public override bool IsBrowsable
{
get
{
return true;
}
}

public override Type ComponentType
{
get { return this.componentType; }
}

public override bool IsReadOnly
{
get { return false; }
}

public override Type PropertyType
{
get { return this.value.GetType(); }
}

public override object GetValue(object component)
{
return this.value;
}

public override bool CanResetValue(object component)
{
return false;
}

public override void ResetValue(object component)
{
}

public override void SetValue(object component, object value)
{
this.value = value;
this.OnPropertyChanged(this.Name);
}

public override bool ShouldSerializeValue(object component)
{
return false;
}

private void OnPropertyChanged(string name)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}

最佳答案

我认为您错误地设置了 ComponentType 属性。

  1. 属性:Person.Child 应该将 ComponentType 设置为 typeof(Person) 而不是 typeof(Child)。就像属性:Person.Name。
  2. 属性:Child.Name 应将 ComponentType 设置为 typeof(Child)。

ComponentType 用于定义属性所有者类型。

关于c# - “绑定(bind)生成器”不询问嵌套的 ICustomTypeDescriptor(路径为空)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12229018/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com