簡體   English   中英

如何在WinRT中創建文件存在轉換器

[英]How to make a File Exists Converter in WinRT

我正在嘗試使用轉換器檢查本地存儲中是否存在圖像源。 如果不與外部網址一起使用。

<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來更改圖像源。

提前致謝。

我想你不希望你的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;   
}

我們正在訪問GetFilesAsync返回的任務的Result屬性,而不是使用await ,阻止我們的方法,直到任務完成。

您的原始代碼准相當於以下內容:

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

核心問題是您需要在同步操作( Convert )中執行async操作。 沒有一種簡單的方法可以做到這一點; 如果可能的話,構造你的代碼,使其不必要(例如,有一個屬性啟動對另一個屬性的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;
}

我現在附近沒有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;
}

我不確定它是否正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM