2010-05-06 129 views
6

我有這樣定義的列: WPF格式顯示文本?

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

不是顯示文件大小作爲一個大數目,我想顯示的單位,但仍然有它排序實際 FileSizeBytes。有什麼方法可以在顯示它之前通過函數或其他東西運行它?


@Igor:

的偉大工程。

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(); 
    } 
} 

回答

2

綁定到一個功能是可以在WPF,但它一般痛苦。在這種情況下,更優雅的方法是創建另一個屬性,該屬性返回格式化的字符串並綁定到該屬性。

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"); 
    } 
    } 
} 

在XAML中,結合FileSizeFormatted

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

EDIT替代的解決方案,由於查理指出了這一點。

您可以通過執行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(); 
    } 
} 

然後在XAML:

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

如果您無法將其他屬性添加到源類(可能有多種原因),則另一種解決方案是創建一個IValueConverter並使用Converter屬性將其綁定到綁定。然後每次綁定更新時,它都會先通過轉換器代碼運行。 – Charlie 2010-05-06 23:23:00

+0

是的,好點。另一種方法是將源代碼包裝在視圖模型中,在某些情況下這可能是一種矯枉過正。 – 2010-05-06 23:35:29

+0

我不想更多屬性的原因是因爲我必須爲它們中的每一個觸發一個PropertyChanged事件......我可以用幾十個觸發器完成所有本質上相同的事情!另外,你將演示文稿與數據綁定在一起。我喜歡第二次sol'n。 – mpen 2010-05-07 01:25:03

1

用於格式化,合適的實現是一個定義的IValueConverter。檢查此示例: link text

4

如果您使用的是.NET 3.5SP1或更高版本,則可以嘗試在綁定表達式中使用StringFormat。有關某些語法示例,請參閱this post on Lester's WPF Blogthis post at Vince Sibal's blog。將StringFormat添加到綁定中將消除對值轉換器的大多數需求,並方便地使用標記保持格式化,而不是在某個地方的另一個類中關閉。當然,打字也少得多。

也許這樣的事情會工作:

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

我不知道,如果點擊標題對項目進行排序將它們分類爲字符串或基本數據類型,雖然如此,這取決於什麼您的格式化表達式看起來像,您可能會也可能不會獲得所需的排序行爲。