单击PropertyGrid时如何获得响应 [英] How to get response when click PropertyGrid

查看:90
本文介绍了单击PropertyGrid时如何获得响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在窗体上有一个PropertyGrid,并挂接了"MouseClick"事件,但是,当我单击PropertyGrid时,没有任何响应(事件)被调用,即,"MouseClick"事件失败.

另外,我尝试编写以下几行:

I have a PropertyGrid on form, and hook the ''MouseClick'' event on, but, when I click on PropertyGrid, there is no any response(event) is invoked, ie, the ''MouseClick'' event fails.

Plus, I try to write the following lines :

foreach (Control c in propertyGrid1.Controls)
{   c.MouseClick += new MouseEventHandler(MyMouseClickEven);   }



它旨在将每个Property与专用的"MouseClick"事件挂钩,但是,不存在"propertyGrid.Controls"行,但是,我看到有"ControlAdded"和"ControlRemoved"属性,为什么没有propertyGrid.Controls?有人可以提供根本原因吗?



It is intended to hook each Property with dedicated ''MouseClick'' event, however, the line of ''propertyGrid.Controls'' is not existed, but, I see there are ''ControlAdded'' and ''ControlRemoved'' attributes, why there is no propertyGrid.Controls ? Can someone provide the root cause ?

推荐答案

答案很简单.使用PropertyGrid时单击的控件不是通过Control.Controls公开的控件.您没有直接访问PropertyGrid所示的实际"编辑控件的权限,这是有充分理由的.

控件PropertyGrid非常特殊;它非常灵活,但是改变其行为的方法却大不相同.我在标准Microsoft文档中找到了此功能的说明(很久以前对于.NET Framework v.2.0).在您对目标进行很好的解释之前,我看不出有理由解释它们(这并不容易).现在,我已经完全回答了您的问题,因为您只是询问了根本原因".

—SA
The answer is simple. The controls you click when working with PropertyGrid are not those exposed via Control.Controls. You do not have direct access to "real" edit controls shown by PropertyGrid — for a good reason.

The control PropertyGrid is very special; it is very flexible, but methods of altering its behavior are very different. I found the description of this functionality in standard Microsoft documentation (for .NET Framework v. 2.0, long time ago). I don''t see a reason to explain them (this is not easy) before you provide really good explanation of your goal. For now, I answered you question in full, because you just asked about a "root cause".

—SA


好的,这是对Sports Kuo后续问题的单独答案:如何自定义目标结构的字段的编辑过去由System.Windows.Forms.PropertyGrid使用其属性SelectedObject进行编辑.
正如我所说(请参阅我对其他答案的评论),该组件并非旨在拦截事件并使用自定义编辑器替换就地编辑器.

该技术是如此复杂,以至于需要花费大量篇幅来解释该技术.由于我不是在写这篇文章,所以我只能示意性地描述这些步骤.并且应从Microsoft常规帮助中获取详细信息.

因此,设计System.Windows.Forms.PropertyGrid建议通过子类修改就地编辑器.除此之外,要调用此类编辑器,属性SelectedObject不应与目标对象一起使用.取而代之的是,该对象应该动态地包装在实现接口System.ComponentModel.ICustomTypeDescriptor的某些类中.让我们将此类命名为"PropertySurrogate".我们还假设代理(包装器)将实际对象用作构造函数参数:PropertySurrogate.PropertySurrogate(object target).完成此操作后,应使用替代代替实际的目标对象:

All right, here is a separate answer to a follow-up question by Sports Kuo: how to customize the editing of the fields of the target structure used to be edited by System.Windows.Forms.PropertyGrid using its property SelectedObject.
As I say (please see my comments to my other answer), this component is not designed to intercept events and replace in-place editor with a custom editor.

The technique is so complex that it would take a whole big article to explain the techniques. As I''m not writing such article, I can only depict the steps schematically; and the detail should be taken from regular Microsoft help.

So, the design System.Windows.Forms.PropertyGrid suggests to modify in-place editor by sub-classing. More than that, to invoke such editor, the property SelectedObject should not be used with the target object. Instead, that object should be dynamically wrapped in some class implemented the interface System.ComponentModel.ICustomTypeDescriptor. Let''s name this class "PropertySurrogate". Let''s also assume the surrogate (wrapper) takes an actual object as a constructor parameter: PropertySurrogate.PropertySurrogate(object target). When this is done, the surrogate should be used instead of actual target object:

System.Windows.Forms.PropertyGrid myPropertyGrid;
object selectedObject = //object of any type usually class or structure

//...

//default behavior:
myPropertyGrid.SelectedObject = selectedObject;

//custom behavior: using custom editor(s) and more:
myPropertyGrid.SelectedObject = new PropertySurrogate(selectedObject);

//...


注意:PropertyGrid本身未修改.它是PropertySurrogate定义了selectedObject表示的所有细节:显示哪些成员,允许哪些成员可编辑以及编辑器.同样,可以使用微型树视图以特殊方式显示嵌套结构(例如,请参见如何显示System.Graphics.Point类型的属性;对于任何其他结构也可以实现相同的效果).

现在,应实施System.ComponentModel.ICustomTypeDescriptor.所有12种接口方法都很重要,其中一种接口方法用于定义编辑器:System.ComponentModel.ICustomTypeDescriptor.GetEditor.可以使用"helper"类System.ComponentModel.TypeDescriptor来实现该接口,但是需要选择某种特殊类型的编辑器的特定实现应提供特殊的编辑器,而不是默认的.

这是我的例子.除了默认的字符串编辑器之外,我还必须实现文本属性编辑器.默认编辑器的行为类似于单行编辑控件,但是我需要一个多行文本编辑器.首先,我需要指定哪些属性值得"多行编辑.为此,我创建了一个特殊属性:


Note: PropertyGrid itself is not modified. It is the PropertySurrogate defines all the detail of the presentation of selectedObject: which members to show, which members are allowed to be editable and the editors. Also, nested structures could be shown in a special way, using miniature tree views (see for example, how the properties of the type System.Graphics.Point are presented; same effect can be achieved for any other structure).

Now, as System.ComponentModel.ICustomTypeDescriptor should be implemented. All 12 of the interface methods are important, one of the interface methods is used to define the editor: System.ComponentModel.ICustomTypeDescriptor.GetEditor. The interface can be implemented using the "helper" class System.ComponentModel.TypeDescriptor, but the particular implementation which need to select some specialized kind of editor should provide special editor instead the default.

Here is my example. I had to implement text-property editor in addition to the default string editor. The default editor behaves like single-line edit control, but I needed a multi-line text editor. First of all, I need to specify which properties "deserve" multi-line editing. For this purpose, I created a special attribute:

[System.AttributeUsage(
    System.AttributeTargets.Property,
    AllowMultiple=false, Inherited=false)]
public class UiMultilineTextAttribute : System.Attribute { }



使用反射,我们需要查看目标对象类型的每个属性,找出应该使用的编辑器(如果有),并将此信息传递给System.ComponentModel.ICustomTypeDescriptor.GetEditor的实现.此实现还应该使用编辑器类型,因此最终将我们带到了编辑器本身.

要通过实现System.ComponentModel.ICustomTypeDescriptor的类来实现供PropertyGrid使用的编辑器,应使用类型System.Drawing.Design.UITypeEditor作为基类来创建一个类:



Using Reflection, we need to look at every property of the target object type, find out what editor should be used (if any) and pass this information to implementation of System.ComponentModel.ICustomTypeDescriptor.GetEditor. This implementation should also use the editor type, so it ultimately brings us to the editor itself.

To implement the editor good for the use by PropertyGrid via the class implementing System.ComponentModel.ICustomTypeDescriptor, one should create a class using the type System.Drawing.Design.UITypeEditor as a base class:

internal class MultilineStringEditor : UITypeEditor {
    //...
    public override UITypeEditorEditStyle GetEditStyle(
        ITypeDescriptorContext context) { /*...*/ }
    public override object EditValue(ITypeDescriptorContext context,
        IServiceProvider provider, object value) { /*...*/ }
    TextBox TextBox = new TextBox();
    //...
} //MultilineStringEditor



这是在编辑器中插入一些控件的方法:



Here is a way to insert some control in the editor:

IWindowsFormsEditorService edSvc =
    (IWindowsFormsEditorService)provider.GetService(
         typeof(IWindowsFormsEditorService));
//...
//... make string from object, assign to TextBox.Text
//... set up TextBox properties
//embed TextBox into the PropertyGrid in the drop-down form:
edSvc.DropDownControl(TextBox);



MultilineStringEditor的实现中,应使用惰性评估技术重新使用TextBox的实例:需要一个文本框实例和一个激活标志作为类MultilineStringEditor的插槽.每个激活只应在该类的实例中进行一次.

这样,我实现了一个特殊的编辑器,其中一个字段用于编辑Multiplicity,另一个特殊的字符串编辑器用于编辑文件名(显示省略号按钮并调用常规File Fialog等).特殊章节是编辑枚举类型的成员.这是一个很大的话题.

有关我的枚举技术的完整课程,请参阅我关于枚举主题的三篇CodeProject系列文章,请在我的CodeProject资料中找到它们.

怎么样?

谢谢.

—SA



In the implementation of MultilineStringEditor the instance of the TextBox should be re-used using lazy evaluation technique: one needs an instance of the text box and an activation flag as the slot of the class MultilineStringEditor. All the activation should be done only once per the instance of the class.

In this way, I implemented special editors with few field in one editor to edit Multiplicity, another special string editor to edit file names (showing ellipsis button calling a regular File Fialog and more. The special chapter is editing enumeration-type members. This is a whole big topic.

For a complete course on my enumeration techniques please see my series of three CodeProject articles on Enumeration topics, please find them in my CodeProject profile.

How''s that?

Thank you.

—SA


这篇关于单击PropertyGrid时如何获得响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆