2009-07-09 2 views
2

요소를 만들고 놓을 수있는 캔버스가 있습니다. 나는 그들을 움직일 수 있고 엄지 손가락으로 또는 재산 격자에 구속력을 가지고 그들을 크기를 정할 수 있습니다.WPF - 캔버스의 위치 및 크기 잠금

이제 위치와 크기를 "고정"하는 기능을 구현해야합니다. 나는 try로 시작하여 min과 max height를 실제 높이 \ width로 설정했다. 초기 노력은 그렇게 크지 않았습니다. 그리고 나는 여전히 위치 고정 전략을 가지고 있지 않습니다.

그래서 나가서 작동하지 않는 25 가지 접근 방식을 따라 가지 전에 누군가가 제안을했습니다. 나는 그것을 고맙게 생각한다.

덕분에, 제프

답변

1

당신은, ... 가능 유지하기 위해 더 나은 것 이상하지 않은 PropertyGrid를 들어, ThumbPropertyGrid ... 물론

을 해제 할 수 그러나 읽기 전용, 불행히도 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); 

동일한 속성을 표시하지만 편집 할 수는 없습니다 ...

OK,이 솔루션은 아마도 사용자의 요구에 조금 과잉입니다 ... 그러나 어떤 경우에는 유용 ​​할 수 있다고 생각합니다.)