WPF - блокировка положения и размера на холсте - PullRequest
2 голосов
/ 10 июля 2009

У меня есть холст, на который я могу создавать и добавлять элементы. Я могу переместить их и изменить их размер большим пальцем или связать их с сеткой свойств.

Теперь мне нужно реализовать функцию, чтобы «зафиксировать» положение и размер. Я начал с попытки установить минимальную и максимальную высоту \ ширину на фактическую высоту \ ширину. Первоначальное усилие было не таким большим. И у меня до сих пор нет стратегии для определения местоположения.

Поэтому, прежде чем я уйду и прохожу 25 подходов, которые не работают, возможно, у кого-то есть предложение. Я был бы очень признателен.

Спасибо, Джеф

1 Ответ

1 голос
/ 10 июля 2009

Вы можете просто отключить Thumb и PropertyGrid ...

Конечно, для PropertyGrid он не идеален ... было бы лучше оставить его включенным, но только для чтения, к сожалению, PropertyGrid не имеет свойства ReadOnly ... Возможное решение было бы обернуть ваш объект в дескриптор пользовательского типа, который будет представлять свойства только для чтения. Вот два класса для достижения этой цели (извините за длинный код ...):

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);
    }
}

Чтобы показать объект target как доступный только для чтения в PropertyGrid, просто сделайте это:

propertyGrid.SelectedObject = new ReadOnlyTypeDescriptor(target);

Это покажет те же свойства, но они не будут редактируемыми ...

Хорошо, это решение, вероятно, немного излишне для ваших нужд ... но я думаю, что в некоторых случаях оно может быть полезно;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...