Hérité Visible / Contrôle activé Propriété Valeur toujours vrai: PropertyGrid
-
30-09-2019 - |
Question
J'ai créé un environnement d'hébergement WinForms personnalisés. Ce qui a une boîte à outils et un PropertyGrid.
Les commandes affichées dans la boîte à outils sont héritées de contrôles WinForm existants.
DropDownList Source:
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
}
J'ai mis en ICustomTypeDescriptor
pour filtrer les propriétés que je ne veux pas montrer dans le PropertyGrid
.
Problème:
Je suis face à problème alors que les valeurs sérialisation des propriétés Enabled
& Visible
qui sont héritées de la classe de System.Windows.Forms.Control
.
WriteProperties Méthode (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;
}
}
}
}
Problème n ° 1:. La méthode ShouldSerializeValue
pour la propriété Enabled
& Visible
retourne toujours false
Problème n ° 2:. Même si je saute la méthode ShouldSerializeValue
vérifier la méthode GetValue
du PropertyDescriptor
retourne toujours True
Current Solution:
Pour contourner ce problème, je l'ai fait actuellement les propriétés Enabled
et Visible
cachés en utilisant la BrowsableAttribute
, et créé deux autres propriétés booléennes et utilisé le DisplayNameAttribute
pour changer leur nom d'affichage pour être Enable
& Visible
.
Mais pour cette solution de contournement je dois écrire ces extraits dans chaque contrôle.
Suis-je manque quelque chose ou faire du tort quoi que ce soit? Pourquoi la propriété Enabled
& Visible
ne changent pas?
La solution
Vous trouverez une longue discussion sur cette question ici . (Lien mort, ne peut pas trouver un nouveau)
la page MSDN aldo fait cette remarque:
La classe InheritedPropertyDescriptor modifie la valeur par défaut d'un la propriété, de sorte que la valeur par défaut est la valeur actuelle à l'objet instanciation. En effet, le propriété est héritée d'un autre exemple. Le concepteur définit la réinitialisation de la valeur de la propriété que la mise à la valeur définie par la classe héritée. Cette valeur peut différente de la valeur par défaut stockée dans les métadonnées.
La valeur de retour de ShouldSerializeValue est basé sur la différence entre la valeur actuelle et la valeur par défaut, donc je pense que cela est directement lié à votre problème.
J'espère que cela vous aidera à comprendre ce qui se passe dans votre propre contexte.