2015-02-02 2 views
0

Я использую WinForms PropertyGrid для отображения различных параметров конфигурации для программы. PropertyGrid привязан к XML-документу, который был Xmlserializer.Deserialize -ed. Это позволяет пользователю вводить новые значения, которые затем сериализуются обратно в файл config.xml. В некоторых случаях эти свойства являются просто цифрами, а впечатывание значений имеет смысл. Однако в других случаях значения представляют собой имена файлов или пути к каталогам, поэтому имеет смысл сделать их введенными через OpenFileDialog или FolderBrowserDialog.Щелкните события из PropertyGrid (например, откройте диалоговое окно файла/папки)

То, что я хотел бы иметь, заключается в том, что если пользователь нажимает на папку или ячейку имени файла в PropertyGrid, пользовательский интерфейс откроет соответствующее диалоговое окно, получит результат и введите этот результат в сетку, заменив существующая стоимость. Проблема в том, что PropertyGrid, похоже, не разрешает доступ к элементам управления внутри него, поэтому я не могу ответить на событие OnClicked.

Вот как я бы как кода для работы (EDIT: обновленный кода):

private void propertyGrid_config_Click(object sender, EventArgs e) 
{ 
    PropertyGrid grid = (PropertyGrid)sender; 
    PropertyDescriptor selectedItem = grid.SelectedGridItem.PropertyDescriptor; 
    if (selectedItem.Category == "Files & Folders") 
    { 
     if (selectedItem.DisplayName.Contains("directory")) 
     { 
      FolderBrowserDialog folder = new FolderBrowserDialog(); 
      if (folder.ShowDialog() == DialogResult.OK) 
      { 
       selectedItem.SetValue(grid.SelectedObject, folder.SelectedPath); 
       grid.Refresh(); 
      } 
     } 
     else if (selectedItem.DisplayName.Contains("file")) 
     { 
      OpenFileDialog file = new OpenFileDialog(); 
      if (file.ShowDialog() == DialogResult.OK) 
      { 
       selectedItem.SetValue(grid.SelectedObject, file.FileName); 
       grid.Refresh(); 
      } 
     } 
    } 
} 

Я набор «нажали» событие сетки для этого обработчика, но очевидно, что не работает так как это обрабатывает контейнер, а не то, что в нем. (Обратите внимание, что этот обработчик отлично работает, если я основываю его на событии «PropertyChanged», но это, очевидно, не то, что я ищу.)

Есть ли способ получить доступ к компонентам и создать события, которые я хочу? Как бы вы справились с этой проблемой?


В случае это уместно, вот некоторые из кода для PropertyGrid:

Сетка существует в классе под названием «Конфигурация», который определяет все свойства, как это:

[Description("Folder for storing Bonding Key logs")] 
[Category("Files & Folders")] 
[DisplayName("Log output directory")] 
public string dirLogOutput { get; set; } 

XML-файл будет иметь соответствующую запись для каждого свойства, подобного этому:

<dirLogOutput>C:\Users\AHoffman\Desktop\TestData</dirLogOutput> 

сериализатором делает хорошую работу согласования данных из файла XML в сетке, и наоборот:

public Configuration TryLoadConfiguration(Configuration thisConfig) 
{ 
    string filename = GetConfigFilename(); 
    try 
    { 
     if (!File.Exists(filename)) 
     { 
      thisConfig.setDefaults(); 
     } 
     else 
     { 
      using (var stream = File.Open(filename, FileMode.Open, FileAccess.Read)) 
      { 
       var serializer = new XmlSerializer(typeof(Configuration)); 
       thisConfig = (Configuration)serializer.Deserialize(stream); 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Failed to load configuration file during startup: " + ex.Message); 
     thisConfig.setDefaults(); 
    } 
    return thisConfig; 
} 

private void SaveConfiguration(string filename, Configuration thisConfig) 
{ 
    try 
    { 
     using (var stream = File.Open(filename, FileMode.Create, FileAccess.Write)) 
     { 
      var serializer = new XmlSerializer(typeof(Configuration)); 
      serializer.Serialize(stream, thisConfig); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Failed to save configuration file: " + ex.Message); 
    } 
} 

Хочу отметить, что вопрос, как это было предложено до here, но без каких-либо ответов. Надеюсь, я дам вам достаточно информации, чтобы что-то вернуть.

ответ

1

ОК неважно. Я нашел ответы на свой вопрос here (для файлов) и here (для папок).

Все полагается на использование пользовательского UITypeEditor для каждого типа.

[EditorAttribute(typeof(OpenFileNameEditor), typeof(System.Drawing.Design.UITypeEditor))] 

[EditorAttribute(typeof(FolderNameEditor2), typeof(System.Drawing.Design.UITypeEditor))] 

Благодаря сильно к @Simon Mourier, @Stewy и @tzup для своих ответов.

Смежные вопросы