0

ファイル サイズを "1 MB" や "2.5 GB" などの文字列形式に変換したいだけです。Q.42 ライブラリからコンバーターを参照しました。XAMLコードに誤りがある可能性があります。これを理解するのを手伝ってください。

MainPage.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インターフェイスを実装し、変更時MyClassPropertyChangedイベントを発生させSizeます。これにより、バインディングが確実に更新されます。

次に、ページのデータ バインディングを のインスタンスに設定しますMyClass

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

あなたが行ったことを示しました。

MyClass3 番目に、 inの新しいインスタンスを作成する代わりに、バインド先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 には通知されません。

OnNavigatedTo作成されたオブジェクト Yで新しいオブジェクトを作成します。代わりに、Sizeオブジェクト X にプロパティを設定する必要がありました。

これをデバッグするには:

  • 最初にコンバーターなしで試して、値が更新されていることを確認してから、コンバーターを追加してください。これにより、コンバーターの問題がバインドの問題から分離されます。
  • のセッターにブレークポイントを設定しSizeます。ヒットした場合、問題はバインディングにあります。そうでない場合、問題は設定されてSizeいないことです。

非常にマイナーな側面: inのulong代わりにa を使用します。s は 64 ビットの精度を提供しますが、53 ビットの精度しか提供しません。バイト単位でこれほど大きなものは見られないかもしれませんが、 のプロパティ タイプとの一貫性も保っています。doubleConvertulongdoublesMainPage

于 2012-09-26T11:45:43.920 に答える