如何在WinRT中创建文件存在转换器

时间:2012-08-30 11:57:17

标签: c# xaml windows-runtime converter

如果本地存储中存在图像源,我正在尝试检查转换器。如果没有使用外部网址。

<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来更改图像源。

先谢谢。

3 个答案:

答案 0 :(得分: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,而是访问Result返回的任务的GetFilesAsync属性,阻止我们的方法,直到任务完成。

您的原始代码几乎等同于以下内容:

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

答案 1 :(得分: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;
}

答案 2 :(得分: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;
}

我不确定它是否有效。