Does WPF format display text?

I have a column defined as follows:

<DataGridTextColumn Binding="{Binding Path=FileSizeBytes, Mode=OneWay}" Header="Size" IsReadOnly="True" /> 

But instead of displaying the file size as a large number, I would like to display units, but still sort it by actual FileSizeBytes . Is there a way to run it through a function or something else before displaying it?


@Igor:

It works great.

http://img200.imageshack.us/img200/4717/imageget.jpg

 [ValueConversion(typeof(long), typeof(string))] class FileSizeConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { string[] units = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; double size = (long)value; int unit = 0; while (size >= 1024) { size /= 1024; ++unit; } return String.Format("{0:0.#} {1}", size, units[unit]); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } 
+6
c # wpf xaml
source share
3 answers

Function binding is possible in WPF, but it usually hurts. In this case, a more elegant approach would be to create another property that returns a formatted string and binds to it.

 class FileInfo { public int FileSizeBytes {get;set;} public int FileSizeFormatted { get{ //Using general number format, will put commas between thousands in most locales. return FileSizeBytes.ToString("G"); } } } 

In XAML, bind to FileSizeFormatted :

 <DataGridTextColumn Binding="{Binding Path=FileSizeBytes, Mode=OneWay}" Header="Size" IsReadOnly="True" /> 

EDIT An alternative solution, thanks to Charlie for pointing this out.

You can write your own value converter by running IValueConverter .

 [ValueConversion(typeof(int), typeof(string))] public class IntConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { //needs more sanity checks to make sure the value is really int //and that targetType is string return ((int)value).ToString("G"); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { //not implemented for now throw new NotImplementedException(); } } 

Then in XAML:

 <UserControl.Resources> <src:DateConverter x:Key="intConverter"/> </UserControl.Resources> ... <DataGridTextColumn Binding="{Binding Path=FileSizeBytes, Mode=OneWay, Converter={StaticResource intConverter}}" Header="Size" IsReadOnly="True" /> 
+2
source share

You can try using StringFormat in your binding expression if you are using .NET 3.5SP1 or later. See this Lester WPF blog post or this Vince Sibal blog post for some syntax examples. Adding StringFormat to the bindings will eliminate most of the needs for value converters and it’s more convenient to store formatting with markup rather than in another class. It certainly prints a lot less.

Perhaps something like this will work:

 <DataGridTextColumn Binding="{Binding Path=FileSizeBytes, Mode=OneWay, StringFormat='\{0:N0\} bytes'}" Header="Size" IsReadOnly="True" /> 

I'm not sure if clicking on the header to sort the elements will sort them as strings or as the underlying data type, however, so depending on what the formatting expression looks like, you may or may not get the desired sorting behavior.

+4
source share

For formatting purposes, the appropriate implementation defines IValueConverter. Check out this sample: link text

+1
source share

All Articles