I have an List values with a ResourceKey and a Caption, these values are both strings. The Resource is the name of an actual resource defined in a resource dictionary. Each of these ResourceKey Icons are Canvas's.
<Data ResourceKey="IconCalendar" Caption="Calendar"/>
<Data ResourceKey="IconEmail" Caption="Email"/>
I then have a list view which has a datatemplate with a button and a text caption below the button. What I want to do is display Resource static resource as the content for the button.
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Content="{Binding ResourceKey}" Template="{StaticResource RoundButtonControlTemplate}"/>
<TextBlock Grid.Row="1" Margin="0,10,0,0" Text="{Binding Caption}" HorizontalAlignment="Center" FontSize="20" FontWeight="Bold" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
I think I have tried every permutation with binding staticresource etc.
I am open to alternatives, I know it may be easier to just have an image and set the source property.
Thanks
After having a little think I ending up using a ValueConvertor
like so:
class StaticResourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var resourceKey = (string)value;
return Application.Current.Resources[resourceKey];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new Exception("The method or operation is not implemented.");
}
}
and the binding on the button becomes
<Button Content="{Binding ResourceKey, Converter={StaticResource resourceConverter}}" />
Here I've got an improved version of @dvkwong 's answer (along with @Anatoliy Nikolaev 's edit):
class StaticResourceConverter : MarkupExtension, IValueConverter
{
private Control _target;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var resourceKey = (string)value;
return _target?.FindResource(resourceKey) ?? Application.Current.FindResource(resourceKey);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var rootObjectProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
if (rootObjectProvider == null)
return this;
_target = rootObjectProvider.RootObject as Control;
return this;
}
}
usage:
<Button Content="{Binding ResourceKey, Converter={design:StaticResourceConverter}}" />
The primary change here is:
The converter is now a System.Windows.Markup.MarkupExtension
so it can be used directly without being declared as a resource.
The converter is context-aware, so it will not only look up in your App's resources, but also local resources (current window, usercontrol or page etc.).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With