。NET Winforms控件需要从PropertyGrid隐藏仅设计器的属性

问题描述 投票:0回答:1

我深入研究在C#/。NET解决方案中使用Winforms设计器(System.ComponentModel.Design命名空间),以便我的用户可以在运行的应用程序中访问表单设计器。它的大部分工作都很好,但是我遇到了一个非常具体的问题:我在Microsoft控件上遇到了一个仅在设计时出现的属性,即该控件在设计时的实例。我想隐藏该属性,以便用户在将该控件的实例放置在我的程序对Winform设计图的实现上时无法对其进行修改。

详细信息:当用户将控件从工具箱拖放到设计器表面时,我确保选择了该控件的新添加的设计器实例(以便它显示调整大小的句柄,以便属性网格显示该控件的设计时属性)。通过使用选择服务的GetSelectedComponents()方法并将属性网格的SelectedObjects属性分配给结果,将设计器表面上的选定对象绑定到属性网格。

我的工具箱上的许多控件都是.NET控件。其中之一是.NET Winforms TableLayoutPanel控件。当将该控件的实例放置在设计器图面上时,将在绑定的[[PropertyGrid中看到一个Columns属性。我想隐藏该属性,以便它不会出现在PropertyGrid中。

问题是,此列属性似乎不存在于

TableLayoutPanel

类型的属性列表中-因此,例如,使用selectedComponents[0].GetType().GetProperties()时不包含Columns属性。另外,我无法为现有的[[Columns属性创建新的或替代的,因为它在设计时并未显示为TableLayoutPanel控件的公开属性-因此,我无法用[C0装饰它]属性。 我似乎无法利用Browsable(false)PreFilterProperties,因为我无法交互和自定义TableLayoutPanel's设计器。

如何隐藏TableLayoutPanel

Columns

设计器属性,以使它不必出现在PropertyGrid中而无需编写我自己的设计器?
c# .net windows-forms-designer
1个回答
0
投票
TableLayoutPanelDesigner是负责调用设计者的ITypeDescriptorFilterService方法的接口。 PreFilterProperties类具有在DesignSurface中注册的该接口的实现的实例。因此,您可以删除现有的注册实例,并注册自己的ServiceContainer实现的新实例。

在新的实现中,重写ITypeDescriptorFilterService并执行您认为合适的任何事情,例如,您可以检查组件的类型是否为FilterProperties,然后不要调用``

示例

仅供参考,您要查找的属性的名称为TableLayoutPanel,默认情况下具有ColumnStyles属性。但是Browsable(false)的默认设计器使用可浏览的版本替换了此属性。

在此示例中,我所做的是阻止设计器使这些属性可见。

首先提供TableLayoutPanel的自定义实现。实际上,以下示例是ITypeDescriptorFilterService程序集中的现有实现,我已经重写了它的System.Design方法,并检查组件是否为FilterProperties,我什么也不做。

TableLayoutPanel

然后通过从using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Windows.Forms; public class TypeDescriptorFilterService : ITypeDescriptorFilterService { internal TypeDescriptorFilterService() { } private IDesigner GetDesigner(IComponent component) { ISite site = component.Site; if (site != null) { IDesignerHost service = site.GetService(typeof(IDesignerHost)) as IDesignerHost; if (service != null) return service.GetDesigner(component); } return (IDesigner)null; } bool ITypeDescriptorFilterService.FilterAttributes(IComponent component, IDictionary attributes) { if (component == null) throw new ArgumentNullException("component"); if (attributes == null) throw new ArgumentNullException("attributes"); IDesigner designer = this.GetDesigner(component); if (designer is IDesignerFilter) { ((IDesignerFilter)designer).PreFilterAttributes(attributes); ((IDesignerFilter)designer).PostFilterAttributes(attributes); } return designer != null; } bool ITypeDescriptorFilterService.FilterEvents(IComponent component, IDictionary events) { if (component == null) throw new ArgumentNullException("component"); if (events == null) throw new ArgumentNullException("events"); IDesigner designer = this.GetDesigner(component); if (designer is IDesignerFilter) { ((IDesignerFilter)designer).PreFilterEvents(events); ((IDesignerFilter)designer).PostFilterEvents(events); } return designer != null; } bool ITypeDescriptorFilterService.FilterProperties(IComponent component, IDictionary properties) { if (component == null) throw new ArgumentNullException("component"); if (properties == null) throw new ArgumentNullException("properties"); if (typeof(TableLayoutPanel).IsAssignableFrom(component.GetType())) return true; IDesigner designer = this.GetDesigner(component); if (designer is IDesignerFilter) { ((IDesignerFilter)designer).PreFilterProperties(properties); ((IDesignerFilter)designer).PostFilterProperties(properties); } return designer != null; } } 派生来创建设计图面:

DesignSurface

然后例如以这种方式初始化设计图面:

using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
public class MyDesignSurface : DesignSurface
{
    public MyDesignSurface() : base()
    {
        this.ServiceContainer.RemoveService(typeof(ITypeDescriptorFilterService));
        this.ServiceContainer.AddService(typeof(ITypeDescriptorFilterService), new TypeDescriptorFilterService());
    }
}

然后运行您的设计器应用程序,您将看到public partial class Form1 : Form { public Form1() { InitializeComponent(); var surface = new MyDesignSurface(); var host = (IDesignerHost)surface.GetService(typeof(IDesignerHost)); var selectionService = (ISelectionService)surface.GetService(typeof(ISelectionService)); surface.BeginLoad(typeof(Form)); var root = (Form)host.RootComponent; var tableLayoutPanel1 = (Control)host.CreateComponent(typeof(TableLayoutPanel), "tableLayoutPanel1"); root.Controls.Add(tableLayoutPanel1); var view = (Control)surface.View; view.Dock = DockStyle.Fill; this.Controls.Add(view); selectionService.SetSelectedComponents(new[] { tableLayoutPanel1 }); var propertyGrid1 = new PropertyGrid() { Dock = DockStyle.Right, Width = 200 }; this.Controls.Add(propertyGrid1); propertyGrid1.SelectedObjects = selectionService.GetSelectedComponents().Cast<object>().ToArray(); } } Columns属性被隐藏了。

您需要隐藏RowsColumnCount属性,以及分配给编辑/添加/删除列和行的动词。
© www.soinside.com 2019 - 2024. All rights reserved.