0

我只想将文件大小转换为字符串格式,如“1 MB”或“2.5 GB”,我认为我从Q.42 库中引用了转换器,我的 XAML 代码可能有错误,请帮我弄清楚这一点。

主页.XAML

<Page.Resources>
    <local:ByteToStringConverter x:Key="BytesToString" />
</Page.Resources>
<Grid>
    <TextBlock Text="{Binding Path=Size, Converter={StaticResource BytesToString}}"/>
</Grid>

MainPage.XAML.cs

public sealed partial class MainPage : Page
{

    public MainPage()
    {
        this.InitializeComponent();
    }

    protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        StorageFile f = await KnownFolders.MusicLibrary.GetFileAsync("video.mp4");
        BasicProperties bs = await f.GetBasicPropertiesAsync();
        MyClass obj = new MyClass();
        obj.Size = bs.Size;
    }
}

public class MyClass : INotifyPropertyChanged
{
    private ulong _Size;

    public ulong Size
    {
        get { return _Size; }
        set { _Size = value; OnPropertyChanged("Size");}
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

ByteToStringConverter.cs

public class ByteToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        string size = "0 KB";

        if (value != null)
        {

            double byteCount = 0;

            byteCount = System.Convert.ToDouble(value);

            if (byteCount >= 1073741824)
                size = String.Format("{0:##.##}", byteCount / 1073741824) + " GB";
            else if (byteCount >= 1048576)
                size = String.Format("{0:##.##}", byteCount / 1048576) + " MB";
            else if (byteCount >= 1024)
                size = String.Format("{0:##.##}", byteCount / 1024) + " KB";
            else if (byteCount > 0 && byteCount < 1024)
                size = "1 KB";    //Bytes are unimportant ;)            
        }

        return size;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
4

1 回答 1

0

[编辑:更新以反映新代码]

首先,实现INotifyPropertyChanged接口,MyClass并在发生更改时触发PropertyChanged事件Size。这将确保更新绑定。

二、将页面的数据绑定设置为 的实例MyClass,如

<Page.DataContext> 
    <local:MyClass/> 
</Page.DataContext>

你已经表明你已经做到了。

第三,不要创建 in 的新实例,而是MyClass在已绑定到OnNavigatedTo的实例上设置属性。MainPage例如:

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    StorageFile f = await KnownFolders.MusicLibrary.GetFileAsync("video.mp4");
    BasicProperties bs = await f.GetBasicPropertiesAsync();

    // Do not create a new instance       
    ((MyClass) DataContext).Size = bs.Size;
}

为什么?WPF 中的绑定是针对特定对象实例完成的。例如,如果控件 A 绑定到对象 X 并且对象 X 的属性发生更改,则控件 A 将被更新。如果控件 A 绑定到对象 X,但另一个对象 Y 的值发生变化,则控件 A 将不会收到通知。

在创建对象 Y 中创建新对象。OnNavigatedTo相反,您想Size在对象 X 上设置属性。

要调试这个:

  • 首先在不使用转换器的情况下尝试以确保值已更新,然后添加转换器。这会将任何转换器问题与绑定问题分开。
  • 在设置器中为Size. 如果它被击中,则问题出在绑定上。如果没有,问题是Size没有设置。

非常次要的一点:使用 aulong而不是doublein Convertulongs 提供 64 位精度,而doubles仅提供 53 位精度。你可能永远看不到这么大的字节数,但它也与MainPage.

于 2012-09-26T11:45:43.920 回答