点击PropertyGrid中的事件(例如打开文件/文件夹对话框)

时间:2015-02-02 21:23:30

标签: c# event-handling propertygrid

我正在使用WinForms PropertyGrid来显示程序的各种配置设置。 PropertyGrid绑定到一个已Xmlserializer.Deserialize - ed的XML文档。这允许用户键入新值,然后将其序列化回config.xml文件。在某些情况下,这些属性只是数字,输入值是有意义的。但是,在其他情况下,值是文件名或目录路径,因此通过OpenFileDialogFolderBrowserDialog输入这些值更有意义。

我想要发生的是if用户点击PropertyGrid中的文件夹或文件名单元格,用户界面将打开相应的对话框,获得结果并将结果输入网格,取代现有的价值。麻烦的是,PropertyGrid似乎不允许访问其中的控件,因此我无法响应OnClicked事件。

以下是喜欢代码的工作原理(编辑:更新代码):

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();
            }
        }
    }
}

我已经设置了网格" Clicked"这个处理程序的事件,但显然不起作用,因为它只处理容器而不是其中的内容。 (注意这个处理程序工作正常,如果我基于" PropertyChanged"事件,但这显然不是我正在寻找的。)

是否有某种方法可以访问组件并创建我想要的事件?你会如何克服这个问题?


如果相关,请参阅PropertyGrid的部分代码:

网格存在于名为"配置"的类中。它定义了所有这些属性:

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

XML文件将为每个Property提供相应的条目,如下所示:

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

Serializer可以很好地将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 个答案:

答案 0 :(得分:1)

好吧没关系。我找到了问题here(对于文件)和here(对于文件夹)的答案。

这一切都依赖于为每种类型使用自定义UITypeEditor

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

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

非常感谢@Simon Mourier@Stewy@tzup的答案。

相关问题