- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在应用程序中实现了 ICustomTypeDescriptor,以便能够在运行时定义自定义属性。我的基本实现如下:
public class DynamicClass <T> : ICustomTypeDescriptor
{
private readonly T _object;
public DynamicClass(T trackedObject)
{
_object = trackedObject;
}
// Collection to code add dynamic properties
public KeyedCollection<string, DynamicProperty> Properties
{
get;
private set;
}
// ICustomTypeDescriptor implementation
public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(_object, true);
}
public string GetClassName()
{
return TypeDescriptor.GetClassName(_object, true);
}
public string GetComponentName()
{
return TypeDescriptor.GetComponentName(_object, true);
}
public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(_object, true);
}
public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(_object, true);
}
public PropertyDescriptor GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(_object, true);
}
public object GetEditor(Type editorBaseType)
{
throw new NotImplementedException();
}
public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(_object, true);
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(_object, attributes, true);
}
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{
return TypeDescriptor.GetProperties(_object, true);
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return TypeDescriptor.GetProperties(_object, attributes, true);
}
public object GetPropertyOwner(PropertyDescriptor pd)
{
return _object;
}
}
问题是,现在当我使用 DynamicClass 绑定(bind)器将对象绑定(bind)到文本框时,它不再起作用。
我这样使用它:
DynamicClass<ExtensionModel> binder = new DynamicClass<ExtensionModel>(ext);
_versionLabel.DataBindings.Add("Text", binder, "SelectedVersion", false, DataSourceUpdateMode.OnPropertyChanged);
我得到了异常:“对象与目标类型不匹配。”
Object does not match target type.
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.ComponentModel.ReflectEventDescriptor.AddEventHandler(Object component, Delegate value) at System.ComponentModel.ReflectPropertyDescriptor.AddValueChanged(Object component, EventHandler handler) at System.Windows.Forms.BindToObject.CheckBinding() at System.Windows.Forms.Binding.SetListManager(BindingManagerBase bindingManagerBase) at System.Windows.Forms.ListManagerBindingsCollection.AddCore(Binding dataBinding) at System.Windows.Forms.BindingsCollection.Add(Binding binding) at System.Windows.Forms.BindingContext.UpdateBinding(BindingContext newBindingContext, Binding binding) at System.Windows.Forms.Control.UpdateBindings()
如果我使用 ext 对象而不是绑定(bind)器,则绑定(bind)有效。我是否错过了 ICustomTypeDescriptor 实现中的某些内容?
最佳答案
您必须用自定义描述符包装原始描述符。这是代码:
#region IBindingProxy
public interface IBindingProxy
{
void CheckAndNotify();
}
#endregion
public class BindingProxy : CustomTypeDescriptor, INotifyPropertyChanged, IBindingProxy
{
#region Static Constructor
private static readonly IDictionary<Type, PropertyDescriptorCollection> propertyCache;
static BindingProxy()
{
propertyCache = new Dictionary<Type, PropertyDescriptorCollection>();
}
private static PropertyDescriptorCollection GetTypeProperties(Type type)
{
lock (propertyCache)
{
PropertyDescriptorCollection properties;
if (!propertyCache.TryGetValue(type, out properties))
{
var list = new List<PropertyDescriptor>();
GetTypeProperties(list, type);
properties = new PropertyDescriptorCollection(list.ToArray());
propertyCache.Add(type, properties);
}
return properties;
}
}
private static void GetTypeProperties(ICollection<PropertyDescriptor> list, Type type)
{
foreach (var @interface in type.GetInterfaces())
{
GetTypeProperties(list, @interface);
}
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(type))
{
list.Add(new ProxyPropertyDescriptor(property));
}
}
#endregion
private readonly PropertyDescriptorCollection properties;
private readonly object instance;
public event PropertyChangedEventHandler PropertyChanged;
public BindingProxy(object instance)
{
this.instance = instance;
properties = instance == null
? PropertyDescriptorCollection .Empty
: GetTypeProperties(instance.GetType());
}
public void CheckAndNotify()
{
OnPropertyChanged(null);
}
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public object Instance
{
get { return instance; }
}
public override PropertyDescriptorCollection GetProperties()
{
return GetProperties(null);
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return properties;
}
public override Object GetPropertyOwner(PropertyDescriptor property)
{
return this;
}
#region ProxyPropertyDescriptor
private class ProxyPropertyDescriptor : PropertyDescriptor
{
private readonly PropertyDescriptor property;
public ProxyPropertyDescriptor(PropertyDescriptor property) : base(property)
{
this.property = property;
}
//public override string DisplayName
//{
// get { return property.DisplayName; }
//}
//public override string Description
//{
// get { return property.Description; }
//}
//public override string Category
//{
// get { return property.Category; }
//}
//public override TypeConverter Converter
//{
// get { return converter; }
//}
public override bool IsReadOnly
{
get { return property.IsReadOnly; }
}
public override void ResetValue(object component)
{
}
public override bool CanResetValue(object component)
{
return false;
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
public override Type ComponentType
{
get { return property.ComponentType; }
}
public override Type PropertyType
{
get { return property.PropertyType; }
}
public override object GetValue(object component)
{
return property.GetValue(((BindingProxy)component).instance);
}
public override void SetValue(object component, object value)
{
var instance = ((BindingProxy)component).instance;
property.SetValue(instance, value);
OnValueChanged(instance, EventArgs.Empty);
}
}
#endregion
}
关于.net - ICustomTypeDescriptor 对象的包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9427587/
我在应用程序中实现了 ICustomTypeDescriptor,以便能够在运行时定义自定义属性。我的基本实现如下: public class DynamicClass : ICustomTypeD
我有一个实现接口(interface)的通用类 (Parameters.cs):ICustomTypeDescriptor。 我将泛型类用于几个不同的类,其中之一是: private Para
我不明白它是什么以及何时使用它。 MSDN 没有帮助我。MSDN 声明 ICustomTypeDescriptor 提供了一个为对象提供动态自定义类型信息的接口(interface)。 最佳答案 有很
我有一个实现 ICustomTypeDescriptor 的类,用户可以在 PropertyGrid 中查看和编辑它。我的类还有一个 IsReadOnly 属性,它确定用户以后是否能够保存他们的更改。
我在 DataGridView 中显示对象列表。一切正常。根据对象的属性自动将列添加到 DataGridView。 现在我更改了我在网格中显示的类以实现 ICustomTypeDescriptor。但
我试图全面了解您如何使用 ICustomTypeDescriptor、TypeDescriptionProvider、TypeConverter 和 UITypeEditor 来更改 Property
在一个测试项目中,我设法在以下场景中自动生成 WPF DataGrid 列,其中数据存储在字典中并通过 PropertyDescriptors 执行绑定(bind): public class Peo
我正在试验 ICustomTypeDescriptor 接口(interface)和 PropertyDescriptor 类,以便在对象上创建动态属性。我在简单对象方面取得了很大成功,但我无法获取嵌
我正在为 ASP.NET MVC 3 开发一个小型库,该库应该提供更好的模型元数据可重用性以及从数据实体到自定义 View 模型的轻松映射。为此,我需要能够为 ASP.NET MVC 的三个不同领域提
如标题所示,我有一个 DataGrid 和一个实现 ICustomTypeDescriptor 的 ViewModel,在运行时添加了一些属性。 public class PartCloneSetti
我是一名优秀的程序员,十分优秀!