4

イメージソースがローカルストレージに存在するかどうかをコンバーターで確認しようとしています。そうでない場合は、外部URLを使用してください。

<Image Source="{Binding Image, Converter={StaticResource ImageCacheConverter}}"/>

これはこれまでの私のコンバーターです:

public object Convert(object value, Type targetType, object parameter, string language)
{
    return IfFileExist((string)value, "localimage.png");
}
public async Task<string> IfFileExist(string value, string filename)
{
    var folder = ApplicationData.Current.LocalFolder;
    var getFilesAsync = await folder.GetFilesAsync(CommonFileQuery.OrderByName);

    var file = getFilesAsync.FirstOrDefault(x => x.Name == filename);
    if (file != null)
    {
        return "ms-appdata:///local/" + filename;
    }
    return (string)value;
}

私が直面している主な問題は、IValueConverter内に非同期があることです。しかし、画像ソースを変更するには、IfFileExistを返す必要があります。

前もって感謝します。

4

3 に答える 3

4

IfFileExistメソッドを非同期で実行したくないと思います。しかし、それはの使用のために起こっていることですawait

これに変更してみてください:

public async Task<System.Collections.Generic.IReadOnlyList<Windows.Storage.StorageFile>> GetFilesAsync()
{
    var folder = ApplicationData.Current.LocalFolder;
    return await folder.GetFilesAsync(CommonFileQuery.OrderByName)
                       .AsTask().ConfigureAwait(false);
}

public string IfFileExist(string value, string filename)   
{   
    var files = GetFilesAsync().Result;

    var file = files.FirstOrDefault(x => x.Name == filename);   
    if (file != null)   
    {   
        return "ms-appdata:///local/" + filename;   
    }   
    return value;   
}

を使用する代わりに、によって返されるタスクのプロパティにawaitアクセスし、タスクが終了するまでメソッドをブロックします。ResultGetFilesAsync

元のコードは、次のコードとほぼ同等です。

public async Task<string> IfFileExist(string value, string filename) 
{ 
    var folder = ApplicationData.Current.LocalFolder; 
    var getFilesAsync = folder.GetFilesAsync(CommonFileQuery.OrderByName); 

    return getFilesAsync.ContinueWith(z => 
    {
        var file = getFilesAsync.FirstOrDefault(x => x.Name == filename); 
        if (file != null) 
        { 
            return "ms-appdata:///local/" + filename; 
        } 
        return (string)value; 
    }
} 
于 2012-08-30T12:08:49.053 に答える
3

async中心的な問題は、同期操作()内で操作を実行する必要があることですConvert。これを行う簡単な方法はありません。可能であれば、必要がないようにコードを構造化します(たとえば、あるasyncプロパティで、「変換」の結果である別のプロパティへの更新を開始します)。

強制的にフィットさせたい場合は、次を使用する必要がありますConfigureAwait(false)

public object Convert(object value, Type targetType, object parameter, string language)
{
  // Note that "Result" will wrap any errors in AggregateException, which is annoying.
  return IfFileExist((string)value, "localimage.png").Result;
}

public async Task<string> IfFileExist(string value, string filename)
{
  var folder = ApplicationData.Current.LocalFolder;
  var getFilesAsync = await folder.GetFilesAsync(CommonFileQuery.OrderByName)
      .AsTask().ConfigureAwait(false);

  var file = getFilesAsync.FirstOrDefault(x => x.Name == filename);
  if (file != null)
  {
    return "ms-appdata:///local/" + filename;
  }
  return (string)value;
}
于 2012-08-30T13:31:27.407 に答える
0

現在、近くにWindows 8がありませんが、次のコードを試してみることをお勧めします(Convertメソッド本体のみ)。

public object Convert(object value, Type targetType, object parameter, string language)   
{
    string result = string.Empty;
    Task.Run(async delegate
    {
        result = await IfFileExist((string)value, "localimage.png");
    }).Wait();

    return result;
}

しかし、それが機能しているかどうかはわかりません。

于 2012-08-30T13:39:43.837 に答える