How to make a file converter in WinRT

I am trying to check with the converter if the image source exists in local storage. If not go with an external url.

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

This is my converter:

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

The main problem I encountered is asynchronous use inside IValueConverter. But I need to return oFileExist to change the image source.

Thanks at Advance.

+4
source share
3 answers

I think you want your IfFileExist method not to execute asynchronously. But this is due to the use of await .

Try changing it to this:

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

Instead of using await we gain access to the Result property of the task returned by GetFilesAsync , blocking our method until the task completes.

Your source code is quasi-equivalent to the following:

 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; } } 
+4
source

The main problem is that you need to perform the async operation in a synchronous operation ( Convert ). This is not an easy way to do this; if possible, structure your code so that it is not necessary (for example, one property starts updating async another property, which is the result of the "conversion").

If you want to try to make it fit, you should use 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; } 
+3
source

I don’t have Windows 8 right now, but I can suggest trying the following code (only the body of the Convert method):

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

I am not sure if it works.

0
source

All Articles