簡體   English   中英

打開OpenFileDialog來更改PropertyGrid控件中屬性的值?

[英]Open a OpenFileDialog to change the value of a property in a PropertyGrid control?

在Windows窗體中,我在PropertyGid控件中表示一個自定義類,該控件具有各種字符串屬性,您可以在下一張圖片中注意到:

在此處輸入圖片說明

問題是我對更改字符串屬性值的當前行為不完全滿意。 對於期望一個文件或目錄的路徑,如“目標”或“工作目錄”的屬性這些屬性,我想知道,如果它可能是可能的和可行的實現類型轉換器/類型描述符,將打開一個OpenFileDialog中單擊時屬性網格中字段右側的向下箭頭。 也就是說,通過OpenFileDialog選擇文件或文件夾,而不是直接在屬性網格中寫入路徑,但是如果我願意,仍然可以選擇直接寫入路徑。

也許.NET Framework類庫已經提供了我要的TypeConverter / TypeDescriptor? 如果沒有,這可能嗎? 以及如何開始這樣做?

還是能夠打開OpenFileDialog來更改PropertyGrid控件中特定屬性的值的任何其他想法?

在我的應用程序中,我有一個帶有圖標文件路徑的屬性,另一個可以帶一個文件或文件夾的屬性以及另一個帶有文件夾路徑的屬性。

因此,我必須為這些屬性中的每一個編寫變體...

最簡單的一種方法是,如果您對FolderBrowserDialog外觀和限制感到滿意,則可以直接在EditorAttribute類中指定System.Windows.Forms.Design.FolderNameEditor類。 否則, Ooki.Dialogs是一個不錯的開源庫,可作為獲得現代外觀對話框的替代方法。

第二個最簡單的方法是用於選擇圖標文件路徑的編輯器:

''' <summary>
''' Provides a user interface for selecting a icon file name.
''' </summary>
''' <seealso cref="FileNameEditor"/>
Friend Class IconFileNameEditor : Inherits FileNameEditor

#Region " Constructors "

    ''' <summary>
    ''' Initializes a new instance of the <see cref="IconFileNameEditor"/> class.
    ''' </summary>
    Public Sub New()
        MyBase.New()
    End Sub

#End Region

#Region " Private Methods "

    ''' <summary>
    ''' Initializes the open file dialog when it is created.
    ''' </summary>
    ''' <param name="ofd">
    ''' The <see cref="OpenFileDialog"/> to use to select a file name.
    ''' </param>
    Protected Overrides Sub InitializeDialog(ByVal dlg As OpenFileDialog)
        MyBase.InitializeDialog(dlg)

        With dlg
            .Multiselect = False
            .RestoreDirectory = True
            .DereferenceLinks = True
            .Filter = "Icon Files (*.ico;*.icl;*.exe;*.dll)|*.ico;*.icl;*.exe;*.dll|Icons|*.ico|Libraries|*.dll|Programs|*.exe"
            .FilterIndex = 1
            .SupportMultiDottedExtensions = True
        End With
    End Sub

#End Region

End Class

為了選擇一個文件路徑或文件夾的路徑,並在搜索的東西已經完成並開放源碼,以避免增加外部的依賴關系到我的項目,我參加了一個自定義的FileFolderDialog中提供的類文章中,我設法寫這樣的編輯器這個:

''' <summary>
''' Provides a user interface for selecting a file or folder name.
''' </summary>
''' <seealso cref="UITypeEditor"/>
Public Class FileOrFolderNameEditor : Inherits UITypeEditor

#Region " Constructors "

    ''' <summary>
    ''' Initializes a new instance of the <see cref="FileOrFolderNameEditor"/> class.
    ''' </summary>
    Public Sub New()
        MyBase.New()
    End Sub

#End Region

#Region " Public Methods"

    ''' <summary>
    ''' Gets the editor style used by the <see cref="UITypeEditor.EditValue(IServiceProvider, Object)"/> method.
    ''' </summary>
    ''' <param name="context">
    ''' An <see cref="ITypeDescriptorContext"/> that can be used to gain additional context information.
    ''' </param>
    ''' <returns>
    ''' A <see cref="UITypeEditorEditStyle"/> value that indicates the style of editor used 
    ''' by the <see cref="UITypeEditor.EditValue(IServiceProvider, Object)"/> method. 
    ''' <para></para>
    ''' If the <see cref="UITypeEditor"/> does not support this method, 
    ''' then <see cref="UITypeEditor.GetEditStyle"/> will return <see cref="UITypeEditorEditStyle.None"/>.
    ''' </returns>
    Public Overrides Function GetEditStyle(ByVal context As ITypeDescriptorContext) As UITypeEditorEditStyle
        Return UITypeEditorEditStyle.Modal
    End Function

    ''' <summary>
    ''' Edits the specified object's value using the editor style indicated by the <see cref="UITypeEditor.GetEditStyle"/> method.
    ''' </summary>
    ''' <param name="context">
    ''' An <see cref="ITypeDescriptorContext"/> that can be used to gain additional context information.
    ''' </param>
    ''' <param name="provider">
    ''' An <see cref="IServiceProvider"/> that this editor can use to obtain services.
    ''' </param>
    ''' <param name="value">
    ''' The object to edit.
    ''' </param>
    ''' <returns>
    ''' The new value of the object. 
    ''' <para></para>
    ''' If the value of the object has not changed, this should return the same object it was passed.
    ''' </returns>
    Public Overrides Function EditValue(ByVal context As ITypeDescriptorContext, ByVal provider As IServiceProvider, ByVal value As Object) As Object

        Using dlg As New OpenFileOrFolderDialog()
            If (dlg.ShowDialog = DialogResult.OK) Then
                Return dlg.SelectedPath
            End If
        End Using

        Return MyBase.EditValue(context, provider, value)

    End Function

#End Region

End Class

真的很簡單。

內置的FileNameEditorFolderNameEditor UI類型編輯FolderNameEditor您可以選擇文件名和文件夾名,例如:

using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
public class MyClass
{
    [Editor(typeof(FileNameEditor), typeof(UITypeEditor))]
    public string FilePath { get; set; }

    [Editor(typeof(FolderNameEditor), typeof(UITypeEditor))]
    public string FolderPath { get; set; }
}

如果要自定義FileNameEditor以僅顯示txt文件,則可以覆蓋其InitializeDialog方法:

public class MyFileNameEditor : FileNameEditor
{
    protected override void InitializeDialog(OpenFileDialog openFileDialog)
    {
        base.InitializeDialog(openFileDialog);
        openFileDialog.Filter = "text files (*.txt)|*.txt";
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM