Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / WPF

Use WPF's ListViw to simulate Windows Explorer with binding

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
21 Aug 2009CPOL2 min read 23.2K   634   3   1
Use WPF's ListViw to simulate Windows Explorer with binding

Introduction

I want simulate explorer’s list view with WPF’s ListView. It’s not difficult to retrieve a folder or a file’s icon and its infomations, DirectoryInfo and FileInfo class provide such information I need, to accomplish this task I design below classes.

Image 1

Image 2

FileSystemBase: An abstract class provide the basic information for folder and file, all the information retrieve from a FileSystemInfo instance.

Folder: Represent a local folder.

File: Represent a local file.

FileSystemCollection: the collection of FileSystemBase, inherit from ObservableCollection.

When use Binding to show these items in a ListView with GridView style I meet a problem: When load a directory, there are sub folders and files in it, so the Collection contains folders and files, I want to show the Length info of a file, so I bind a GridViewColumn to Length property, the file item can show it correctly, but the folder item doesn’t has a Length property, when load a folder item an exception will be throwed, more folder loaded more exception throwed.

The exception will cause the application become slow, and the most important reason is I don’t like unhandled exception in my application, so I must solve it.

Image 3

(Exceptions in output window)

To solve this big problem (at least to me it is big) I use CellTemplate first, in the template I judge whether the given ojbect's type is a File item, if true binding the TextBlock’s text property to File’s Length property, else set the TextBlock’s text to null. The CellTemplate looks below.

XML
<DataTemplate x:Key="SizeTemplate" >
    <TextBlock Name="size" Text="{x:Null}" />
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Type}" Value="{x:Type local:File}">
             <Setter TargetName="size" Property="Text" Value="{Binding Length}"/>
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

This way work correctly, but it has a observious shortcomming, it is difficult to extend, if there is another object that also have Length property, but isn't a File item, the CellTemplate can’t show it correctly.

Second I solve this problem with a converter, I tell the converter to retrieve which property’s value, if doesn’t find the property the converter will return null. The converter method.

C#
/// <summary>
///
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object Convert ( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
    if ( !string.IsNullOrEmpty ( mPropertyName ) )
    {
        PropertyDescriptor prop = TypeDescriptor.GetProperties ( value ) [ mPropertyName ];
        if ( prop != null )
            return prop.GetValue ( value );
        else
            return null;
    }
    return null;
}

Definition of PropertyConverter in XAML and usage.

<local:PropertyConverter x:Key="lengthConverter" PropertyName="Length" />

<GridViewColumn Header="Size" DisplayMemberBinding="{Binding Converter={StaticResource lengthConverter}}" Width="120" />

With this solution there are no exception throwed and the converter is reusable. I am not sure this a good and correct solution for the problem, but it works. If you have much better approach for it, please let me know.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralAlternative solution. Pin
Leung Yat Chun21-Aug-09 10:48
Leung Yat Chun21-Aug-09 10:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.