Getting TaskCanceledException in a property update methodHow do I enumerate the properties of a JavaScript object?How to efficiently count the number of keys/properties of an object in JavaScript?What is the difference between a field and a property?Does C# have extension properties?How to get the list of properties of a class?Sorting JavaScript Object by property valueDynamically access object property using variableUsing @property versus getters and settersHow to call asynchronous method from synchronous method in C#?How does the @property decorator work?
Eliminate key lookup in execution plan
What caused the end of cybernetic implants?
How to understand payment due date for credit card?
Which is the correct version of Mussorgsky's Pictures at an Exhibition?
Can inductive kick be discharged without freewheeling diode, in this example?
Magnetic thread storage?
What was Captain Marvel supposed to do once she reached her destination?
Can copper pour be used as an alternative to large traces?
Padding a column of lists
What are T. S. Eliot’s “Jellicle Cats” and “Pollicle Dogs”?
Are sweatpants frowned upon on flights?
'spazieren' - walking in a silly and affected manner?
Are spot colors limited and why CMYK mix is not treated same as spot color mix?
Link between subject and reflexive pronoun
How can I improve my formal definitions
Calculate Landau's function
How to investigate an unknown 1.5GB file named "sudo" in my Linux home directory?
How were US credit cards verified in-store in the 1980's?
Am I required to correct my opponent's assumptions about my morph creatures?
What is this "opened" cube called?
Can two aircraft be allowed to stay on the same runway at the same time?
IList<T> implementation
Is "prohibition against," a double negative?
Why are JWST optics not enclosed like HST?
Getting TaskCanceledException in a property update method
How do I enumerate the properties of a JavaScript object?How to efficiently count the number of keys/properties of an object in JavaScript?What is the difference between a field and a property?Does C# have extension properties?How to get the list of properties of a class?Sorting JavaScript Object by property valueDynamically access object property using variableUsing @property versus getters and settersHow to call asynchronous method from synchronous method in C#?How does the @property decorator work?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I've got the following XAML helper class that allows me to select a bitmap image based on a key:
namespace GammaFour.Views.Controls
using System;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Imaging;
/// <summary>
/// Provides an image from a store.
/// </summary>
public class BitmapSourceSelector : BitmapSource
/// <summary>
/// The Category DependencyProperty.
/// </summary>
public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register(
"Category",
typeof(string),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(string)));
/// <summary>
/// The Dictionary DependencyProperty.
/// </summary>
public static readonly DependencyProperty DictionaryProperty = DependencyProperty.Register(
"Dictionary",
typeof(UriDictionary),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(UriDictionary)));
/// <summary>
/// The Key DependencyProperty.
/// </summary>
public static readonly DependencyProperty KeyProperty = DependencyProperty.Register(
"Key",
typeof(string),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(string), BitmapSourceSelector.OnKeyPropertyChanged));
/// <summary>
/// Gets or sets the category used to select the source for the icon.
/// </summary>
public string Category
get
return this.GetValue(BitmapSourceSelector.CategoryProperty) as string;
set
this.SetValue(BitmapSourceSelector.CategoryProperty, value);
/// <summary>
/// Gets or sets the dictionary of URIs.
/// </summary>
public UriDictionary Dictionary
get
return this.GetValue(BitmapSourceSelector.DictionaryProperty) as UriDictionary;
set
this.SetValue(BitmapSourceSelector.DictionaryProperty, value);
/// <summary>
/// Gets or sets the key used to select the source for the icon.
/// </summary>
public string Key
get
return this.GetValue(BitmapSourceSelector.KeyProperty) as string;
set
this.SetValue(BitmapSourceSelector.KeyProperty, value);
/// <summary>
/// Invoked when the effective property value of the Key property changes.
/// </summary>
/// <param name="dependencyObject">The DependencyObject on which the property has changed value.</param>
/// <param name="dependencyPropertyChangedEventArgs">
/// Event data that is issued by any event that tracks changes to the effective value of this property.
/// </param>
private static async void OnKeyPropertyChanged(
DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
// Extract the changed properties.
string key = dependencyPropertyChangedEventArgs.NewValue as string;
BitmapSourceSelector bitmapSourceSelector = dependencyObject as BitmapSourceSelector;
// Select a source for the image based on the new key.
if (!string.IsNullOrEmpty(key) && bitmapSourceSelector.Dictionary != null)
Uri uri = bitmapSourceSelector.Dictionary.GetUri(bitmapSourceSelector.Category, key);
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
await bitmapSourceSelector.SetSourceAsync(stream);
When executing the OnKeyPropertyChanged method, I get an exception:
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
A task was canceled.
The exception happens during this call:
await bitmapSourceSelector.SetSourceAsync(stream);
If I replace the SetSourceAsync with SetSource, it runs fine. The exception happens somewhat randomly, which usually indicates that the await isn't returning on the Window thread, but I can't find a way to force it. So I've got two questions:
- What's wrong with this code? Why won't it await (the synchronous
version appears to work just fine, which supports the
hypothesis that the call isn't returning on the right thread). - Does anyone have a better way of associating a Bitmap resource with
a value? Theoretically, the View Model shouldn't have any
knowledge of the View and the Bitmap resources are clearly aspects
of the view.
EDIT: Nico Zhu asked for the supporting classes. Here they are:
UriCategory:
/// <summary>
/// A category of URIs.
/// </summary>
public class UriCategory : Dictionary<string, UriSource>
UriDictionary:
/// <summary>
/// A dictionary of URIs organized by category.
/// </summary>
public class UriDictionary : Dictionary<string, UriCategory>
/// <summary>
/// Gets the URI associated with the category, key keys.
/// </summary>
/// <param name="category">The category of the URIs.</param>
/// <param name="key">The key for the URI.</param>
/// <returns>The URI entered into the dictionary with the category, key index.</returns>
internal Uri GetUri(string category, string key)
// This URI is returned if there's no matching entry for the keys.
Uri uri = default(Uri);
// Use the two dictionary levels to find the URI.
UriCategory resourceCategory;
if (this.TryGetValue(category, out resourceCategory))
UriSource resourceSource;
if (resourceCategory.TryGetValue(key, out resourceSource))
uri = resourceSource.Uri;
// The URI belonging to the compound key.
return uri;
And here's the usage in XAML:
<!-- Metadata Image Dictionary -->
<dbcontrols:UriDictionary x:Key="MetadataImages">
<dbcontrols:UriCategory x:Key="Small">
<dbcontrols:UriSource x:Key="Alert"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Alert.png"/>
<dbcontrols:UriSource x:Key="Blotter"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Blotter.png"/>
<dbcontrols:UriSource x:Key="Folder"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Folder.png"/>
<dbcontrols:UriSource x:Key="Portfolio"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Portfolio.png"/>
</dbcontrols:UriCategory>
<dbcontrols:UriCategory x:Key="Medium">
<dbcontrols:UriSource x:Key="Alert"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Alert.png"/>
<dbcontrols:UriSource x:Key="Blotter"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Folder.png"/>
<dbcontrols:UriSource x:Key="Folder"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Folder.png"/>
<dbcontrols:UriSource x:Key="Portfolio"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Portfolio.png"/>
</dbcontrols:UriCategory>
</dbcontrols:UriDictionary>
And here's how to use the image dictionary to display an image based on a key. This design allows the View Model to not require any knowledge of the View in order to display images with data.
<Grid Height="160"
Width="190">
<Image.Source>
<dbcontrols:BitmapSourceSelector Category="Medium"
Dictionary="StaticResource MetadataImages"
Key="Binding ImageKey"/>
</Image.Source>
</Image>
</Grid>
Again, if you know a better way to do this that removes the View Model from the View, I'd be grateful for an example.
uwp properties async-await
add a comment |
I've got the following XAML helper class that allows me to select a bitmap image based on a key:
namespace GammaFour.Views.Controls
using System;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Imaging;
/// <summary>
/// Provides an image from a store.
/// </summary>
public class BitmapSourceSelector : BitmapSource
/// <summary>
/// The Category DependencyProperty.
/// </summary>
public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register(
"Category",
typeof(string),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(string)));
/// <summary>
/// The Dictionary DependencyProperty.
/// </summary>
public static readonly DependencyProperty DictionaryProperty = DependencyProperty.Register(
"Dictionary",
typeof(UriDictionary),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(UriDictionary)));
/// <summary>
/// The Key DependencyProperty.
/// </summary>
public static readonly DependencyProperty KeyProperty = DependencyProperty.Register(
"Key",
typeof(string),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(string), BitmapSourceSelector.OnKeyPropertyChanged));
/// <summary>
/// Gets or sets the category used to select the source for the icon.
/// </summary>
public string Category
get
return this.GetValue(BitmapSourceSelector.CategoryProperty) as string;
set
this.SetValue(BitmapSourceSelector.CategoryProperty, value);
/// <summary>
/// Gets or sets the dictionary of URIs.
/// </summary>
public UriDictionary Dictionary
get
return this.GetValue(BitmapSourceSelector.DictionaryProperty) as UriDictionary;
set
this.SetValue(BitmapSourceSelector.DictionaryProperty, value);
/// <summary>
/// Gets or sets the key used to select the source for the icon.
/// </summary>
public string Key
get
return this.GetValue(BitmapSourceSelector.KeyProperty) as string;
set
this.SetValue(BitmapSourceSelector.KeyProperty, value);
/// <summary>
/// Invoked when the effective property value of the Key property changes.
/// </summary>
/// <param name="dependencyObject">The DependencyObject on which the property has changed value.</param>
/// <param name="dependencyPropertyChangedEventArgs">
/// Event data that is issued by any event that tracks changes to the effective value of this property.
/// </param>
private static async void OnKeyPropertyChanged(
DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
// Extract the changed properties.
string key = dependencyPropertyChangedEventArgs.NewValue as string;
BitmapSourceSelector bitmapSourceSelector = dependencyObject as BitmapSourceSelector;
// Select a source for the image based on the new key.
if (!string.IsNullOrEmpty(key) && bitmapSourceSelector.Dictionary != null)
Uri uri = bitmapSourceSelector.Dictionary.GetUri(bitmapSourceSelector.Category, key);
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
await bitmapSourceSelector.SetSourceAsync(stream);
When executing the OnKeyPropertyChanged method, I get an exception:
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
A task was canceled.
The exception happens during this call:
await bitmapSourceSelector.SetSourceAsync(stream);
If I replace the SetSourceAsync with SetSource, it runs fine. The exception happens somewhat randomly, which usually indicates that the await isn't returning on the Window thread, but I can't find a way to force it. So I've got two questions:
- What's wrong with this code? Why won't it await (the synchronous
version appears to work just fine, which supports the
hypothesis that the call isn't returning on the right thread). - Does anyone have a better way of associating a Bitmap resource with
a value? Theoretically, the View Model shouldn't have any
knowledge of the View and the Bitmap resources are clearly aspects
of the view.
EDIT: Nico Zhu asked for the supporting classes. Here they are:
UriCategory:
/// <summary>
/// A category of URIs.
/// </summary>
public class UriCategory : Dictionary<string, UriSource>
UriDictionary:
/// <summary>
/// A dictionary of URIs organized by category.
/// </summary>
public class UriDictionary : Dictionary<string, UriCategory>
/// <summary>
/// Gets the URI associated with the category, key keys.
/// </summary>
/// <param name="category">The category of the URIs.</param>
/// <param name="key">The key for the URI.</param>
/// <returns>The URI entered into the dictionary with the category, key index.</returns>
internal Uri GetUri(string category, string key)
// This URI is returned if there's no matching entry for the keys.
Uri uri = default(Uri);
// Use the two dictionary levels to find the URI.
UriCategory resourceCategory;
if (this.TryGetValue(category, out resourceCategory))
UriSource resourceSource;
if (resourceCategory.TryGetValue(key, out resourceSource))
uri = resourceSource.Uri;
// The URI belonging to the compound key.
return uri;
And here's the usage in XAML:
<!-- Metadata Image Dictionary -->
<dbcontrols:UriDictionary x:Key="MetadataImages">
<dbcontrols:UriCategory x:Key="Small">
<dbcontrols:UriSource x:Key="Alert"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Alert.png"/>
<dbcontrols:UriSource x:Key="Blotter"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Blotter.png"/>
<dbcontrols:UriSource x:Key="Folder"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Folder.png"/>
<dbcontrols:UriSource x:Key="Portfolio"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Portfolio.png"/>
</dbcontrols:UriCategory>
<dbcontrols:UriCategory x:Key="Medium">
<dbcontrols:UriSource x:Key="Alert"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Alert.png"/>
<dbcontrols:UriSource x:Key="Blotter"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Folder.png"/>
<dbcontrols:UriSource x:Key="Folder"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Folder.png"/>
<dbcontrols:UriSource x:Key="Portfolio"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Portfolio.png"/>
</dbcontrols:UriCategory>
</dbcontrols:UriDictionary>
And here's how to use the image dictionary to display an image based on a key. This design allows the View Model to not require any knowledge of the View in order to display images with data.
<Grid Height="160"
Width="190">
<Image.Source>
<dbcontrols:BitmapSourceSelector Category="Medium"
Dictionary="StaticResource MetadataImages"
Key="Binding ImageKey"/>
</Image.Source>
</Image>
</Grid>
Again, if you know a better way to do this that removes the View Model from the View, I'd be grateful for an example.
uwp properties async-await
could you shareUriDictionary
for us?
– Nico Zhu - MSFT
Mar 28 at 6:05
add a comment |
I've got the following XAML helper class that allows me to select a bitmap image based on a key:
namespace GammaFour.Views.Controls
using System;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Imaging;
/// <summary>
/// Provides an image from a store.
/// </summary>
public class BitmapSourceSelector : BitmapSource
/// <summary>
/// The Category DependencyProperty.
/// </summary>
public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register(
"Category",
typeof(string),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(string)));
/// <summary>
/// The Dictionary DependencyProperty.
/// </summary>
public static readonly DependencyProperty DictionaryProperty = DependencyProperty.Register(
"Dictionary",
typeof(UriDictionary),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(UriDictionary)));
/// <summary>
/// The Key DependencyProperty.
/// </summary>
public static readonly DependencyProperty KeyProperty = DependencyProperty.Register(
"Key",
typeof(string),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(string), BitmapSourceSelector.OnKeyPropertyChanged));
/// <summary>
/// Gets or sets the category used to select the source for the icon.
/// </summary>
public string Category
get
return this.GetValue(BitmapSourceSelector.CategoryProperty) as string;
set
this.SetValue(BitmapSourceSelector.CategoryProperty, value);
/// <summary>
/// Gets or sets the dictionary of URIs.
/// </summary>
public UriDictionary Dictionary
get
return this.GetValue(BitmapSourceSelector.DictionaryProperty) as UriDictionary;
set
this.SetValue(BitmapSourceSelector.DictionaryProperty, value);
/// <summary>
/// Gets or sets the key used to select the source for the icon.
/// </summary>
public string Key
get
return this.GetValue(BitmapSourceSelector.KeyProperty) as string;
set
this.SetValue(BitmapSourceSelector.KeyProperty, value);
/// <summary>
/// Invoked when the effective property value of the Key property changes.
/// </summary>
/// <param name="dependencyObject">The DependencyObject on which the property has changed value.</param>
/// <param name="dependencyPropertyChangedEventArgs">
/// Event data that is issued by any event that tracks changes to the effective value of this property.
/// </param>
private static async void OnKeyPropertyChanged(
DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
// Extract the changed properties.
string key = dependencyPropertyChangedEventArgs.NewValue as string;
BitmapSourceSelector bitmapSourceSelector = dependencyObject as BitmapSourceSelector;
// Select a source for the image based on the new key.
if (!string.IsNullOrEmpty(key) && bitmapSourceSelector.Dictionary != null)
Uri uri = bitmapSourceSelector.Dictionary.GetUri(bitmapSourceSelector.Category, key);
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
await bitmapSourceSelector.SetSourceAsync(stream);
When executing the OnKeyPropertyChanged method, I get an exception:
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
A task was canceled.
The exception happens during this call:
await bitmapSourceSelector.SetSourceAsync(stream);
If I replace the SetSourceAsync with SetSource, it runs fine. The exception happens somewhat randomly, which usually indicates that the await isn't returning on the Window thread, but I can't find a way to force it. So I've got two questions:
- What's wrong with this code? Why won't it await (the synchronous
version appears to work just fine, which supports the
hypothesis that the call isn't returning on the right thread). - Does anyone have a better way of associating a Bitmap resource with
a value? Theoretically, the View Model shouldn't have any
knowledge of the View and the Bitmap resources are clearly aspects
of the view.
EDIT: Nico Zhu asked for the supporting classes. Here they are:
UriCategory:
/// <summary>
/// A category of URIs.
/// </summary>
public class UriCategory : Dictionary<string, UriSource>
UriDictionary:
/// <summary>
/// A dictionary of URIs organized by category.
/// </summary>
public class UriDictionary : Dictionary<string, UriCategory>
/// <summary>
/// Gets the URI associated with the category, key keys.
/// </summary>
/// <param name="category">The category of the URIs.</param>
/// <param name="key">The key for the URI.</param>
/// <returns>The URI entered into the dictionary with the category, key index.</returns>
internal Uri GetUri(string category, string key)
// This URI is returned if there's no matching entry for the keys.
Uri uri = default(Uri);
// Use the two dictionary levels to find the URI.
UriCategory resourceCategory;
if (this.TryGetValue(category, out resourceCategory))
UriSource resourceSource;
if (resourceCategory.TryGetValue(key, out resourceSource))
uri = resourceSource.Uri;
// The URI belonging to the compound key.
return uri;
And here's the usage in XAML:
<!-- Metadata Image Dictionary -->
<dbcontrols:UriDictionary x:Key="MetadataImages">
<dbcontrols:UriCategory x:Key="Small">
<dbcontrols:UriSource x:Key="Alert"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Alert.png"/>
<dbcontrols:UriSource x:Key="Blotter"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Blotter.png"/>
<dbcontrols:UriSource x:Key="Folder"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Folder.png"/>
<dbcontrols:UriSource x:Key="Portfolio"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Portfolio.png"/>
</dbcontrols:UriCategory>
<dbcontrols:UriCategory x:Key="Medium">
<dbcontrols:UriSource x:Key="Alert"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Alert.png"/>
<dbcontrols:UriSource x:Key="Blotter"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Folder.png"/>
<dbcontrols:UriSource x:Key="Folder"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Folder.png"/>
<dbcontrols:UriSource x:Key="Portfolio"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Portfolio.png"/>
</dbcontrols:UriCategory>
</dbcontrols:UriDictionary>
And here's how to use the image dictionary to display an image based on a key. This design allows the View Model to not require any knowledge of the View in order to display images with data.
<Grid Height="160"
Width="190">
<Image.Source>
<dbcontrols:BitmapSourceSelector Category="Medium"
Dictionary="StaticResource MetadataImages"
Key="Binding ImageKey"/>
</Image.Source>
</Image>
</Grid>
Again, if you know a better way to do this that removes the View Model from the View, I'd be grateful for an example.
uwp properties async-await
I've got the following XAML helper class that allows me to select a bitmap image based on a key:
namespace GammaFour.Views.Controls
using System;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Imaging;
/// <summary>
/// Provides an image from a store.
/// </summary>
public class BitmapSourceSelector : BitmapSource
/// <summary>
/// The Category DependencyProperty.
/// </summary>
public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register(
"Category",
typeof(string),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(string)));
/// <summary>
/// The Dictionary DependencyProperty.
/// </summary>
public static readonly DependencyProperty DictionaryProperty = DependencyProperty.Register(
"Dictionary",
typeof(UriDictionary),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(UriDictionary)));
/// <summary>
/// The Key DependencyProperty.
/// </summary>
public static readonly DependencyProperty KeyProperty = DependencyProperty.Register(
"Key",
typeof(string),
typeof(BitmapSourceSelector),
new PropertyMetadata(default(string), BitmapSourceSelector.OnKeyPropertyChanged));
/// <summary>
/// Gets or sets the category used to select the source for the icon.
/// </summary>
public string Category
get
return this.GetValue(BitmapSourceSelector.CategoryProperty) as string;
set
this.SetValue(BitmapSourceSelector.CategoryProperty, value);
/// <summary>
/// Gets or sets the dictionary of URIs.
/// </summary>
public UriDictionary Dictionary
get
return this.GetValue(BitmapSourceSelector.DictionaryProperty) as UriDictionary;
set
this.SetValue(BitmapSourceSelector.DictionaryProperty, value);
/// <summary>
/// Gets or sets the key used to select the source for the icon.
/// </summary>
public string Key
get
return this.GetValue(BitmapSourceSelector.KeyProperty) as string;
set
this.SetValue(BitmapSourceSelector.KeyProperty, value);
/// <summary>
/// Invoked when the effective property value of the Key property changes.
/// </summary>
/// <param name="dependencyObject">The DependencyObject on which the property has changed value.</param>
/// <param name="dependencyPropertyChangedEventArgs">
/// Event data that is issued by any event that tracks changes to the effective value of this property.
/// </param>
private static async void OnKeyPropertyChanged(
DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
// Extract the changed properties.
string key = dependencyPropertyChangedEventArgs.NewValue as string;
BitmapSourceSelector bitmapSourceSelector = dependencyObject as BitmapSourceSelector;
// Select a source for the image based on the new key.
if (!string.IsNullOrEmpty(key) && bitmapSourceSelector.Dictionary != null)
Uri uri = bitmapSourceSelector.Dictionary.GetUri(bitmapSourceSelector.Category, key);
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
await bitmapSourceSelector.SetSourceAsync(stream);
When executing the OnKeyPropertyChanged method, I get an exception:
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
A task was canceled.
The exception happens during this call:
await bitmapSourceSelector.SetSourceAsync(stream);
If I replace the SetSourceAsync with SetSource, it runs fine. The exception happens somewhat randomly, which usually indicates that the await isn't returning on the Window thread, but I can't find a way to force it. So I've got two questions:
- What's wrong with this code? Why won't it await (the synchronous
version appears to work just fine, which supports the
hypothesis that the call isn't returning on the right thread). - Does anyone have a better way of associating a Bitmap resource with
a value? Theoretically, the View Model shouldn't have any
knowledge of the View and the Bitmap resources are clearly aspects
of the view.
EDIT: Nico Zhu asked for the supporting classes. Here they are:
UriCategory:
/// <summary>
/// A category of URIs.
/// </summary>
public class UriCategory : Dictionary<string, UriSource>
UriDictionary:
/// <summary>
/// A dictionary of URIs organized by category.
/// </summary>
public class UriDictionary : Dictionary<string, UriCategory>
/// <summary>
/// Gets the URI associated with the category, key keys.
/// </summary>
/// <param name="category">The category of the URIs.</param>
/// <param name="key">The key for the URI.</param>
/// <returns>The URI entered into the dictionary with the category, key index.</returns>
internal Uri GetUri(string category, string key)
// This URI is returned if there's no matching entry for the keys.
Uri uri = default(Uri);
// Use the two dictionary levels to find the URI.
UriCategory resourceCategory;
if (this.TryGetValue(category, out resourceCategory))
UriSource resourceSource;
if (resourceCategory.TryGetValue(key, out resourceSource))
uri = resourceSource.Uri;
// The URI belonging to the compound key.
return uri;
And here's the usage in XAML:
<!-- Metadata Image Dictionary -->
<dbcontrols:UriDictionary x:Key="MetadataImages">
<dbcontrols:UriCategory x:Key="Small">
<dbcontrols:UriSource x:Key="Alert"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Alert.png"/>
<dbcontrols:UriSource x:Key="Blotter"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Blotter.png"/>
<dbcontrols:UriSource x:Key="Folder"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Folder.png"/>
<dbcontrols:UriSource x:Key="Portfolio"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Small/Portfolio.png"/>
</dbcontrols:UriCategory>
<dbcontrols:UriCategory x:Key="Medium">
<dbcontrols:UriSource x:Key="Alert"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Alert.png"/>
<dbcontrols:UriSource x:Key="Blotter"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Folder.png"/>
<dbcontrols:UriSource x:Key="Folder"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Folder.png"/>
<dbcontrols:UriSource x:Key="Portfolio"
Uri="ms-appx:///GammaFour.InvestmentManagement.Views/Assets/Medium/Portfolio.png"/>
</dbcontrols:UriCategory>
</dbcontrols:UriDictionary>
And here's how to use the image dictionary to display an image based on a key. This design allows the View Model to not require any knowledge of the View in order to display images with data.
<Grid Height="160"
Width="190">
<Image.Source>
<dbcontrols:BitmapSourceSelector Category="Medium"
Dictionary="StaticResource MetadataImages"
Key="Binding ImageKey"/>
</Image.Source>
</Image>
</Grid>
Again, if you know a better way to do this that removes the View Model from the View, I'd be grateful for an example.
uwp properties async-await
uwp properties async-await
edited Mar 28 at 23:39
Donald Airey
asked Mar 27 at 23:09
Donald AireyDonald Airey
1,82021 silver badges30 bronze badges
1,82021 silver badges30 bronze badges
could you shareUriDictionary
for us?
– Nico Zhu - MSFT
Mar 28 at 6:05
add a comment |
could you shareUriDictionary
for us?
– Nico Zhu - MSFT
Mar 28 at 6:05
could you share
UriDictionary
for us?– Nico Zhu - MSFT
Mar 28 at 6:05
could you share
UriDictionary
for us?– Nico Zhu - MSFT
Mar 28 at 6:05
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55387855%2fgetting-taskcanceledexception-in-a-property-update-method%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Is this question similar to what you get asked at work? Learn more about asking and sharing private information with your coworkers using Stack Overflow for Teams.
Is this question similar to what you get asked at work? Learn more about asking and sharing private information with your coworkers using Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55387855%2fgetting-taskcanceledexception-in-a-property-update-method%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
could you share
UriDictionary
for us?– Nico Zhu - MSFT
Mar 28 at 6:05