我们有一个自定义面板,该面板继承了Panel并具有与SplitContainer Orientation属性类似的Orientation属性。对于我们的自定义面板,DockStyle.Fill永远无效,根据Orientation属性值,DockStyle的“垂直”需要为“左”或“右”,而“水平”则需要为“ DockStyle.Fill”。

DockStyleEditor类是密封的,因此我们不能为我们自己的自定义UITypeEditor子类化。有没有一种方法可以使用TypeDescriptor或其他方式覆盖某些行为?

我们想对“属性网格”中的自定义面板DockStyle编辑器进行以下操作:
  1.禁用中间的“填充”按钮或将其显示为带有红色斜线的圆圈,以表明该按钮不可用
  2.当“方向”属性为水平时,禁用“顶部”和“底部”按钮
  3.当“方向”属性为垂直时,禁用“向左”和“向右”按钮

最佳答案

DockEditor是密封的,但是您可以基于DockEditor创建自定义的停靠编辑器,而无需继承它。在您的自定义UITypeEditor中,您可以创建DockEditor的实例,并使用反射操作其编辑器控件,然后使用它执行值编辑。

DockEditor使用作为私有类的DockUI控件。它具有用于None按钮和容器控件的复选框,其中包含用于FillTopLeftRightBottom的复选框。
然后,您可以根据逻辑简单地更改EnabledBackColor或其他属性。

在下面的代码中,我将找到那些复选框按钮,并将禁用FillTopBottomNone。用户可用的唯一选项是LeftRight

public class MyDockEditor : UITypeEditor
{
    DockEditor editor;
    public MyDockEditor()
    {
        editor = new System.Windows.Forms.Design.DockEditor();
    }
    public override object EditValue(ITypeDescriptorContext context,
                                     IServiceProvider provider, object value)
    {
        Type dockUiType = typeof(DockEditor)
               .GetNestedType("DockUI", BindingFlags.NonPublic);
        var dockUiConstructor = dockUiType.GetConstructors()[0];
        var dockUiField = typeof(DockEditor)
               .GetField("dockUI", BindingFlags.Instance | BindingFlags.NonPublic);
        var dockUiObject = dockUiConstructor.Invoke(new[] { editor }) as Control;
        dockUiField.SetValue(editor, dockUiObject);
        var container = dockUiObject.Controls[0];
        var none = dockUiObject.Controls[1];
        var fill=  container.Controls[0];
        var left= container.Controls[1];
        var right= container.Controls[2];
        var top = container.Controls[3];
        var bottom = container.Controls[4];
        none.Enabled = false;
        fill.Enabled = false;
        top.Enabled = false;
        bottom.Enabled = false;
        return editor.EditValue(context, provider, value);
    }
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return editor.GetEditStyle(context);
    }
}


要使用它,只需用Editor属性装饰控件的Dock属性即可:

[Editor(typeof(MyDockEditor), typeof(UITypeEditor))]
public override DockStyle Dock
{
    get { return base.Dock; }
    set { base.Dock = value; }
}


如您在下图中看到的,仅启用了左侧和右侧。

c# - 如何覆盖PropertyGrid中DockStyle编辑器的行为-LMLPHP

关于c# - 如何覆盖PropertyGrid中DockStyle编辑器的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36192542/

10-10 22:18