2009-07-09 7 views
2

J'ai une toile que je peux créer et déposer des éléments. Je peux les déplacer et les dimensionner avec un pouce ou en liant à une grille de propriété. Maintenant, j'ai besoin de mettre en œuvre une fonctionnalité pour "verrouiller" la position et la taille. J'ai commencé par essayer et définir les tailles min et max hauteur \ largeur par rapport à la hauteur \ largeur réelle. L'effort initial n'était pas si bon. Et je n'ai toujours pas de stratégie pour fixer l'emplacement. Donc, avant que je ne parte et parcourir 25 approches qui ne fonctionnent pas, peut-être quelqu'un a une suggestion. J'apprécierais beaucoup.WPF - Verrouiller Position et taille sur une toile

Merci, jeff

Répondre

1

Vous pouvez tout simplement désactiver le Thumb et PropertyGrid ...

Bien sûr, pour PropertyGrid il est idéal ... il serait préférable de le garder activé, mais en lecture seule, malheureusement le PropertyGrid n'a pas de propriété ReadOnly ... Une solution possible serait d'envelopper votre objet dans un descripteur de type personnalisé qui présenterait les propriétés en lecture seule. Voici deux classes pour y parvenir (désolé pour le long code ...):

ReadOnlyTypeDescriptor:

public class ReadOnlyTypeDescriptor : ICustomTypeDescriptor 
{ 
    public ReadOnlyTypeDescriptor(object target) 
    { 
     TypeDescriptionProvider provider = TypeDescriptor.GetProvider(target); 
     _originalDescriptor = provider.GetTypeDescriptor(target); 
    } 

    public ReadOnlyTypeDescriptor(ICustomTypeDescriptor descriptor) 
    { 
     _originalDescriptor = descriptor; 
    } 

    private ICustomTypeDescriptor _originalDescriptor; 

    private PropertyDescriptor MakeReadOnly(PropertyDescriptor propertyDescriptor) 
    { 
     return new ReadOnlyPropertyDescriptor(propertyDescriptor); 
    } 

    private PropertyDescriptorCollection MakeReadOnly(PropertyDescriptorCollection propertyDescriptors) 
    { 
     var descriptors = propertyDescriptors 
          .Cast<PropertyDescriptor>() 
          .Select(pd => new ReadOnlyPropertyDescriptor(pd)) 
          .ToArray(); 
     return new PropertyDescriptorCollection(descriptors, true); 
    } 

    #region ICustomTypeDescriptor Members 

    public AttributeCollection GetAttributes() 
    { 
     return _originalDescriptor.GetAttributes(); 
    } 

    public string GetClassName() 
    { 
     return _originalDescriptor.GetClassName(); 
    } 

    public string GetComponentName() 
    { 
     return _originalDescriptor.GetComponentName(); 
    } 

    public TypeConverter GetConverter() 
    { 
     return _originalDescriptor.GetConverter(); 
    } 

    public EventDescriptor GetDefaultEvent() 
    { 
     return _originalDescriptor.GetDefaultEvent(); 
    } 

    public PropertyDescriptor GetDefaultProperty() 
    { 
     return MakeReadOnly(_originalDescriptor.GetDefaultProperty()); 
    } 

    public object GetEditor(Type editorBaseType) 
    { 
     return _originalDescriptor.GetEditor(editorBaseType); 
    } 

    public EventDescriptorCollection GetEvents(Attribute[] attributes) 
    { 
     return _originalDescriptor.GetEvents(attributes); 
    } 

    public EventDescriptorCollection GetEvents() 
    { 
     return _originalDescriptor.GetEvents(); 
    } 

    public PropertyDescriptorCollection GetProperties(Attribute[] attributes) 
    { 
     return MakeReadOnly(_originalDescriptor.GetProperties(attributes)); 
    } 

    public PropertyDescriptorCollection GetProperties() 
    { 
     return MakeReadOnly(_originalDescriptor.GetProperties()); 
    } 

    public object GetPropertyOwner(PropertyDescriptor pd) 
    { 
     return _originalDescriptor.GetPropertyOwner(pd); 
    } 

    #endregion 
} 

ReadOnlyPropertyDescriptor:

public class ReadOnlyPropertyDescriptor : PropertyDescriptor 
{ 
    public ReadOnlyPropertyDescriptor(PropertyDescriptor descriptor) 
     : base(
      descriptor.Name, 
      descriptor.Attributes.Cast<Attribute>().ToArray()) 
    { 
     _originalDescriptor = descriptor; 
    } 

    private PropertyDescriptor _originalDescriptor; 

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

    public override Type ComponentType 
    { 
     get { return _originalDescriptor.ComponentType; } 
    } 

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

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

    public override Type PropertyType 
    { 
     get { return _originalDescriptor.PropertyType; } 
    } 

    public override void ResetValue(object component) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void SetValue(object component, object value) 
    { 
     throw new NotSupportedException(); 
    } 

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

Pour afficher l'objet target en lecture seule dans le PropertyGrid, juste faire cela:

propertyGrid.SelectedObject = new ReadOnlyTypeDescriptor(target); 

Il montrera les mêmes propriétés, mais ils ne seront pas éditables ...

OK, cette solution est probablement un peu exagérée pour vos besoins ... mais je pense que ça peut être pratique dans certains cas;)

Questions connexes