Click here to Skip to main content
Click here to Skip to main content

Use WPF's ListViw to simulate Windows Explorer with binding

, 21 Aug 2009
Rate this:
Please Sign up or sign in to vote.
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.

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.

(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.

<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.

 
        /// <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)

Share

About the Author

Andy Lang
Architect
China China
No Biography provided

Comments and Discussions

 
GeneralAlternative solution. PinmemberLeung Yat Chun21-Aug-09 10:48 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 21 Aug 2009
Article Copyright 2009 by Andy Lang
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid