Откройте OpenFileDialog, чтобы изменить значение свойства в элементе управления PropertyGrid?

В Windows Forms я представляю пользовательский класс в элементе управления PropertyGid, который имеет различные строковые свойства, как вы можете заметить на следующем изображении:

Откройте OpenFileDialog, чтобы изменить значение свойства в элементе управления PropertyGrid?

Проблема в том, что я не полностью удовлетворен текущим поведением при изменении значения строковых свойств. Для тех свойств, которые ожидают путь к файлу или каталогу, таких как свойства «Цель» или «Рабочий каталог», я хотел бы знать, возможно ли и целесообразно реализовать TypeConverter / Type Descriptor, который открывал бы OpenFileDialog при нажатии в стрелка вниз справа от поля в сетке свойств. То есть, чтобы выбрать файл или папку через OpenFileDialog, вместо того, чтобы напрямую писать путь в сетке свойств, но при этом оставить возможность напрямую написать путь, если я хочу это сделать.

Может быть, библиотека классов .NET Framework уже предоставляет TypeConverter/TypeDescriptor, который я запрашиваю? Если нет, то возможно ли это сделать? И как начать это делать?

Или любая другая идея, чтобы иметь возможность открыть OpenFileDialog, чтобы изменить значение определенного свойства в элементе управления PropertyGrid?.

Фреймворк ничего не знает об IShellLink. Создайте модальный UITypeEditor для настройки редактирования значений.

Hans Passant 28.05.2019 14:59

@Hans Passant Спасибо за комментарий. Я начну с практики на примере кода по адресу: docs.microsoft.com/en-us/dotnet/api/system.drawing.design.ui‌​typeeditor?view=netf‌​ramework-4.8, но отмечу, что эти свойства имеют строковый тип данных.

ElektroStudios 28.05.2019 15:05

По-видимому, есть встроенный UITypeEditor с именем класса FileNameEditor, который может делать то, что мне нужно, или, по крайней мере, это то, что предлагается здесь: stackoverflow.com/a/2373374/1248295. Я еще не пробовал.

ElektroStudios 28.05.2019 15:09

Этот редактор открывает стандартный диалог выбора файлов (Открыть файл) и позволяет выбрать путь/имя файла.

Jimi 28.05.2019 15:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
862
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В моем приложении у меня есть свойство, которое принимает путь к файлу значка, другое свойство, которое может принимать файл или папку, и другое свойство, которое принимает путь к папке.

Итак, мне пришлось написать варианты для каждого из этих свойств...

Самый простой, и в случае, если вас устраивает внешний вид FolderBrowserDialog и ограничения, это напрямую указать класс System.Windows.Forms.Design.FolderNameEditor в классе EditorAttribute. В остальном Ооки.Диалоги — хорошая библиотека с открытым исходным кодом в качестве альтернативы для получения современного диалогового окна.

Второй самый простой — это редактор для выбора пути к файлу иконки:

''' <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

Это было вообще легко.

Ответ принят как подходящий

Существуют встроенные редакторы типов пользовательского интерфейса FileNameEditor и 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 для отображения только текстовых файлов, вы можете переопределить его метод InitializeDialog:

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

Другие вопросы по теме