Microsoft.Win32.OpenFileDialog WPF

时间:2012-08-13 08:32:53

标签: c# .net wpf openfiledialog

我正在使用Microsoft.win32.OpenFileDialog打开SQLCE数据库文件(.sdf)。我添加了以下过滤器* .sdf,因此它只显示.sdf文件,但我还要求它从对话窗口中删除特定的.sdf文件。我想要删除的数据库的名称是固定的,但我无法控制其他数据库被调用的内容,因为它们是通过应用程序创建的,用户决定通过应用程序为它们命名的内容。

我想要实现的一个例子就是说,我有以下数据库

Database1.sdf Database2.sdf Database3.sdf

我想得到除database2.sdf

以外的所有内容

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:1)

OFD很棘手。它是一个通用的文件选择器,旨在尽可能地提供帮助" - 用于文件。过滤器只是用户的小助手。他们不会阻止选择其他文件。

运行画笔或您的应用程序,打开文件选择器。在文件类型组合框中,您可能会看到一些过滤器,实际上对话框将仅显示该文件。输入" *"作为文件名,然后按确定/回车键。现在几乎可以看到所有文件,无论过滤器

这种行为对你有用吗?如果你想隐藏那个对话框中的一些文件,我认为不是。如果我是对的,那么OFD根本不适合你,你应该编写自己的简单" SDF数据库选择器",在ListView / etc上构建,只列出你想要显示的内容

另外,如果没有问题,那么你可以将HANDLE(在.Net中它们作为IntPtr传递)到窗口,然后检查窗口结构以找到它上面的(IIRC)SysListView控件,然后与它交谈以删除不需要的元素。所有工作都将由C ++或P / Invoke完成。如果你真的需要,我会尝试找一些链接。给我留言。

-
对于初学者,抱歉错误输入了组件名称。窗口分为SysListView32

首先,浏览一些文章。要小心,因为大多数都引用System.Windows.Forms,而不是WPF。大多数信息是正确和相关的,因为在内部,它仍然是相同的组件,jsut包装有点不同。

一旦你成功拦截了打开窗口的动作,并且你得到了SHELLDLL_DefView / SysListView32控件的HANDLE(IntPtr),你就可以玩真实的游戏了。

控件,尽管它的名字" SysListView32"实际上命名为" ListView"来自comctl32.dll几乎与Windows本身一样古老。您可以通过发送"原始winapi消息来轻松地动态地重新配置控件。它,但丑陋的是,在.Net中没有很好的办法。您必须P / Invoke到SendMessage,所以请在MSDN上阅读该功能。它的第一个参数HWND只是你刚刚找到的HANDLE(IntPtr)(HWND = [H] andle-to- [W] i [ND] ow)。

控件名为" ListView"了解很多不同的信息。控件是一个Window,因此它理解WM_xxxx消息([W] indow [M] essage_xxx)。并且还理解blahblahblah,更重要的是,它还以LVM_xxxx消息([L] ist [V] iew [M] essage_xxxx)的形式定义其自己的API,例如LVM_GETITEM。请注意,在LVM_GETITEM页面上有大量其他LVM_xxx消息:GETITEMCOUNT,INSERTITEM,DELETEITEM等.LVM_DELETEITEM是您实现目标的关键之一。以下是关于如何删除"第三行"中项目的an example in VB。一行,因为ListView的自然视图是基于网格/行的。类似于桌面的显示模式是一个补充,每个项目在逻辑上仍然被认为是连续的行,而不是X-Y网格单元格。好吧,好吧,除了DESKTOP和自由格式图标放置,这也是由SysListView32完成的,但那是另一个故事..

这是关于ListViews的一组很好的文章:http://msdn.microsoft.com/en-us/library/windows/desktop/bb774737(v=vs.85).aspx 请注意,您必须将所有内容翻译为C#和P / Invoke。

本机控件名为ListView,实际上,[System.Windows.Forms.ListView]是它的.Net包装器!但是,没有很好的方法将该类的实例绑定到预先存在的本机组件实例。该类旨在从头开始创建新的本机ListView组件。如果你在谷歌搜索上有技巧或运气,你可以尝试将这样的ListView绑定到本机Listview,然后你会跳过一些P / Invoke麻烦,但我不认为它真的值得..

手动驾驶/修补/手动控制甚至更复杂一些,例如,您有时可能需要让他们记住它们以在更改后更新屏幕:http://www.codeproject.com/Questions/181852/ListView-corrupt-after-LVM_DELETEITEM-message。更重要的是,过滤项目不是一次性工作。当用户在文件夹树中上下导航时,您必须一次又一次地过滤tham。当用户显示另一个文件夹的某些新内容时,您必须找到一种方法来获得通知。幸运的是,每个使用LVM的人都必须使用现在使用的相同API。这意味着文件对话框必须向控件发送一系列LVI_DELETExxx / LVI_INSERTxxx消息,并且您可能试图拦截+检查+过滤掉它们,因此"坏项目"当物品被列入清单时,它会立即被踢出去。这是我对如何做到这一点的建议"轻松"。

我希望这可以帮助您解决问题。总的来说,除非您之前使用过本机控件和P / Invoke几次,否则这并不容易。我只是鼓励你重新思考你的问题:在简单的文件名验证和消息框中真的无法解决问题"抱歉,你不能使用这个文件"?这将容易几个数量级。

对不起,我找不到任何完整/准确的代码来获取句柄,阅读和删除项目。我知道我几年前见过这样的例子,但现在我找不到任何:(也许我有时间去抓一个例子,但不要指望,我不知道我什么时候有时间进一步解决这个问题。

答案 1 :(得分:0)

您将遇到的一个问题是,即使文件可以隐藏在文件浏览器中,用户仍然可以在对话框的文本部分输入文件名。该文件确实存在,因此就对话框而言,它将是一个有效的选择,并且该行为将难以覆盖。

您不能轻易强制对话框不选择存在的文件,但您可以轻松验证对话框返回的数据。我建议您在对话框关闭后验证文件名,并做出适当的反应。