Heredada de control / Visible Activada Propiedad Valor siempre es cierto: PropertyGrid
-
30-09-2019 - |
Pregunta
He creado un entorno de alojamiento WinForms personalizados. Que tiene una caja de herramientas y una PropertyGrid.
Los controles representada en la caja de herramientas se heredan de controles WinForm existentes.
DropDownList Fuente:
public interface IPropertyFilter : ICustomTypeDescriptor
{
PropertyDescriptorCollection FilterProperties(PropertyDescriptorCollection pdc);
List<string> GetPropertiesToShow();
}
[Serializable]
public class DropDownList : System.Windows.Forms.ComboBox, IPropertyFilter
{
public DropDownList()
{
}
#region IPropertyFilter Members
public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}
EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}
public string GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}
public object GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}
public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this, attributes, true);
return FilterProperties(pdc);
}
PropertyDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetProperties()
{
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this, true);
return FilterProperties(pdc);
}
public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
public PropertyDescriptor GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(this, true);
}
public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}
public string GetClassName()
{
return TypeDescriptor.GetClassName(this, true);
}
public PropertyDescriptorCollection FilterProperties(PropertyDescriptorCollection pdc)
{
// Filter out properties that we do not want to display in PropertyGrid
return ControlDesignerHelper.GetBrowsableProperties(pdc, GetPropertiesToShow());
}
// Determines what properties of this control has to be shown in PropertyGrid
public List<string> GetPropertiesToShow()
{
// get a list of common properties that we want to show for all controls
List<string> browsableProps = ControlDesignerHelper.GetBasePropertiesToShow();
// add properties that are specific to this controls
browsableProps.Add("Items");
browsableProps.Add("AutoPostBack");
browsableProps.Add("AppendDataBoundItems");
browsableProps.Add("DataTextField");
browsableProps.Add("DataValueField");
return browsableProps;
}
#endregion
}
Me han implementado ICustomTypeDescriptor
para filtrar las propiedades que no quiero mostrar en el PropertyGrid
.
Problema:
Estoy frente a un problema, mientras que la serialización de valores de las propiedades Enabled
y Visible
que se heredan de la clase System.Windows.Forms.Control
.
WriteProperties Método (BasicDesignerLoader
):
private void WriteProperties(XmlDocument document, PropertyDescriptorCollection properties, object value, XmlNode parent, string elementName)
{
foreach (PropertyDescriptor prop in properties)
{
System.Diagnostics.Debug.WriteLine(prop.Name);
if (prop.ShouldSerializeValue(value))
{
string compName = parent.Name;
XmlNode node = document.CreateElement(elementName);
XmlAttribute attr = document.CreateAttribute("name");
attr.Value = prop.Name;
node.Attributes.Append(attr);
DesignerSerializationVisibilityAttribute visibility = (DesignerSerializationVisibilityAttribute)prop.Attributes[typeof(DesignerSerializationVisibilityAttribute)];
switch (visibility.Visibility)
{
case DesignerSerializationVisibility.Visible:
if (!prop.IsReadOnly && WriteValue(document, prop.GetValue(value), node))
{
parent.AppendChild(node);
}
break;
case DesignerSerializationVisibility.Content:
object propValue = prop.GetValue(value);
if (typeof(IList).IsAssignableFrom(prop.PropertyType))
{
WriteCollection(document, (IList)propValue, node);
}
else
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(propValue, propertyAttributes);
WriteProperties(document, props, propValue, node, elementName);
}
if (node.ChildNodes.Count > 0)
{
parent.AppendChild(node);
}
break;
default:
break;
}
}
}
}
Problema # 1:. El método ShouldSerializeValue
para la propiedad Enabled
y Visible
siempre devuelve false
Problema # 2:. Incluso si me salto el método ShouldSerializeValue
comprobar el método de la GetValue
PropertyDescriptor
siempre devuelve True
Solución actual:
Como solución que he hecho actualmente las propiedades Enabled
y Visible
ocultos utilizando el BrowsableAttribute
, y creó otras dos propiedades booleanas y se utiliza la DisplayNameAttribute
para cambiar su nombre para mostrar para ser Enable
y Visible
.
Sin embargo, para que esta solución que tengo que escribir estos fragmentos en cada control.
Me estoy perdiendo algo o haciendo mal algo? ¿Por qué la Enabled
y propiedad Visible
no cambian?
Solución
A continuación encontrará una larga discusión sobre este tema aquí . (Vínculo roto, no puede encontrar uno nuevo)
MSDN página aldo hace que este Observación:
La clase InheritedPropertyDescriptor modifica el valor predeterminado de una propiedad, por lo que el valor por defecto es el valor actual en el objeto instanciación. Esto se debe a la propiedad se hereda de otra ejemplo. El distribuidor determina diseñador restablecer el valor de la propiedad como estableciéndolo en el valor que se establece por la clase heredada. Este valor puede diferir del valor predeterminado almacenado en los metadatos.
valor de retorno de ShouldSerializeValue se basa en la diferencia entre el valor actual y el valor por defecto, así que creo que esto está directamente relacionado con su problema.
Espero que esto le ayudará a averiguar qué sucede en su propio contexto.