在应用程序中,如果需要用户选择文件,就会用到OpenFileDialog 控件,这个控件来可以方便用户选择文件。它提供了一些属性,其中比较重要的是“Filter”属性,它能够使用后缀来筛选过滤文件。如下代码,当弹出选择文件对话框时,在后缀的下拉选择框里,能够选择显示.txt文件或所有文件。

var fileContent = string.Empty;
var filePath = string.Empty;

using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
    openFileDialog.InitialDirectory = "c:\\";
    openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
    openFileDialog.FilterIndex = 2;
    openFileDialog.RestoreDirectory = true;

    if (openFileDialog.ShowDialog() == DialogResult.OK)
    {
        //Get the path of specified file
        filePath = openFileDialog.FileName;

        //Read the contents of the file into a stream
        var fileStream = openFileDialog.OpenFile();

        using (StreamReader reader = new StreamReader(fileStream))
        {
            fileContent = reader.ReadToEnd();
        }
    }
}

     打开对话框如下:

     上述代码中“Filter”定义了两种后缀类型的筛选,一个是.txt文件,一个是所有文件,“FilterIndex”属性指定了默认选择的后缀,这个FilterIndex很有意思,竟然不是从0开始,如果你设置为0或者1,那么默认"txt files(*.txt)"文件会选中;设置为大于等于2则“All files(*.*)”被选中。

     这个Filter属性有一个需要注意的地方,比如如果我想同时筛选多个后缀的文件,比如图片文件里各种图片类型可以用分号分隔。比如:

OpenFileDialog openFile=new OpenFileDialog(); 
openFile.Filter="*.jpg,*.png,*.jpeg,*.bmp,*.gif|*.jgp;*.png;*.jpeg;*.bmp;*.gif|All files(*.*)|*.*";

    那么下拉第一项就是所有后缀为.jpg,.png,.jpeg,.bmp,.gif的都会列出来。

    如果不填写Filter,则会列出所有文件。

局限和解决方法


    OpenFilterDialog只能够根据后缀来筛选过滤待选择的文件列表,假如即使在选则了某一类型文件之后,这个列表依然很庞大,能不能进一步根据文件名来筛选呢?比如能否只显示所有以“MD”开头的.txt文件?

    这里就需要用到“FileName"属性,这个属性可以设置或者获取OpenFileDialog中的文件名,这个属性如果不设置,那么当打开选择框时文件名那里会显示丑陋的控件名称"openFileDialog1",一般需要显示的设置为空。

    这里如果我们需要根据文件名过滤,可以使用通配符*,比如下面我只想过滤以MD开头的.txt文件。

openFileDialog.FileName = "MD*";
openFileDialog.Filter = "*txt files (*.txt)|*.txt|All files(*.*)|*.*";
openFileDialog.Multiselect = false;
openFileDialog.FilterIndex = 1;

   目的达到了,但这里仍然有很多局限,比如他不会像Windows里文件搜索那样,高亮匹配的项;比如我想反悔了,删掉这个MD*,列表不会刷新,需要手动点击列表右键鼠标点击刷新才能重新显示。但这已经是在不改动OpenFileDialog的前提下,仅有的能根据文件名过滤待选择文件列表的方法了。

▲ Windows文件搜索高亮显示匹配关键字

 

     更进一步的方法是自己实现一个OpenFileDialog或者扩展现有的OpenFileDialog,这个虽然不难,但是也有些繁琐。

参考: