控件集合的设计时编辑器支持

Design-time editor support for controls collection(控件集合的设计时编辑器支持)
本文介绍了控件集合的设计时编辑器支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I'd like to add a property which represents a collection of controls to a component and have a collection editor with which I can easily select the controls that belong to the collection. VS does almost what I want automatically with the following code:

    Private _controls As New List(Of Control)
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    Public ReadOnly Property SelectedControls() As List(Of Control)
        Get
            Return _controls
        End Get
    End Property

I get the default CollectionEditor, can add and remove controls, and the collection is serialized.

The problem is that I don't want to add new controls, I want to select multiple controls from the other available controls on the form. Is there any easy/standard way to do this, or will I have to write my own collection editor and run through the controls collection?

Although there's plenty of material on collection editors (UITypeEditors) and other design-time topics, I haven't been able to find any links demonstrating this exact behaviour, so any help is appreciated.

解决方案

OK, so in the mean time I've had lunch and written the editor myself. Wasn't such a great effort. I'd be glad to share, if it helps.

Edit: Solution Summary

I wrote an editor (see screenshot) which recursively lists all the controls found on the form in a treeview. If the controls have their Text or Image properties set the text/image is displayed. The user can select multiple controls with checkboxes and even filter the list to only display controls of certain types.

(I must admit, though, that since this editor was only intended for internal use, I didn't bother to check for the image property generically, I just handle a couple of well-known control types.)

The code in the editor form is really just for the UI, responsible for filling the tree, setting the checks on the list of pre-selected controls and returning the list of selected controls when the user closes the form with OK.

Next, we have a class that implements UITypeEditor, which I called FormControlSelectionEditor. This class is assigned to the properties which we want to use the editor for using the [Editor] attribute. It doesn't do much more than create a new instance of the form when required and display it as a modal dialog.

Then there are the properties themselves, which are of type System.Collections.ObjectModel.ObservableCollection(Of Control). I chose ObservableCollection because I need to react to changes to the lists at run-time as well, but other lists would do just as well with minor adaptation.

One thing I discovered is that I had to write my properties and editor such that they use copies of the lists of controls. In other words, the UITypeEditor code makes a copy of the list stored in the property and passes it to the editor form (for setting the checks when the form is opened), and when the form is closed, I clear the property's backing list and copy over each control in the list returned from the editor. I found that otherwise I had problems with serialization in the .designer file. I don't believe it has to be this way; I think it's more likely an error on my part.

Code for a typical property:

    Private WithEvents _insertButtons As New System.Collections.ObjectModel.ObservableCollection(Of Control)
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    <Editor(GetType(Design.FormControlSelectionEditor), GetType(UITypeEditor))> _
    Public Property InsertButtons() As System.Collections.ObjectModel.ObservableCollection(Of Control)
        Get
            Return _insertButtons
        End Get
        Set(ByVal value As System.Collections.ObjectModel.ObservableCollection(Of Control))
            If value Is Nothing Then
                RemoveInsertButtonEventHandlers(_insertButtons)
                _insertButtons.Clear()
            Else
                ' Copy the list items passed in into the internal list
                For i As Integer = _insertButtons.Count - 1 To 0 Step -1
                    If Not value.Contains(_insertButtons.Item(i)) Then _insertButtons.RemoveAt(i)
                Next
                For Each ctl As Control In value
                    If Not _insertButtons.Contains(ctl) Then _insertButtons.Add(ctl)
                Next
            End If
        End Set
    End Property
    Private Function ShouldSerializeInsertButtons() As Boolean
        Return _insertButtons.Count > 0
    End Function
    Private Sub ResetInsertButtons()
        InsertButtons = Nothing
    End Sub

I've put the editor into a zip file; download it here.

As I mentioned before, this was just a quick & dirty solution intended for internal use only. All the same, I'd appreciate any suggestions for improvement.

这篇关于控件集合的设计时编辑器支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
quot;Overflowquot; compiler error with -9223372036854775808L(编译器错误-9223372036854775808L(Q;溢出Q))
Visual Studio 2010 ReportViewer Assembly References(Visual Studio 2010 ReportViewer程序集引用)
Weird behaviour when I open a reportviewer in WPF(在WPF中打开报表查看器时出现奇怪的行为)
how do i pass parameters to aspnet reportviewer(如何将参数传递给aspnet report查看器)