This isn't MahApps.Metro-specific, but that happens to be what I'm using. I have a set of ViewModels that have a string
property representing which icon to use from a resource XAML file.
public class CommandViewModel : ViewModel
{
public CommandViewModel(string displayName, ICommand command, string icon)
{
if (command == null)
throw new ArgumentNullException("command");
DisplayName = displayName;
Command = command;
Icon = icon;
}
public ICommand Command { get; private set; }
public string Icon { get; set; }
}
Icon
would end up being something like "appbar_add" from MahApps.Metro.Resources. These are defined in an Icons.xaml file.
How do I write this up in my ItemTemplate
such that the correct resource shows. I'm either getting errors on execution (not at edit/build) or I'm getting no icons at all.
The "no icon" XAML looks like this:
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Width="20" Height="20">
<Rectangle.Fill>
<VisualBrush Visual="{DynamicResource {Binding Path=Icon}}" />
</Rectangle.Fill>
</Rectangle>
<TextBlock Margin="15,6">
<Hyperlink Command="{Binding Path=Command}">
<TextBlock Text="{Binding Path=DisplayName}" />
</Hyperlink>
</TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
My attempts that caused errors were using StaticResource
, which I think is fundamentally incorrect.
How should I be referencing the Icon
property as the name of the resource I want?
Edit
More code was requested, so here's an example of what does work:
<Rectangle Width="20" Height="20">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource appbar_add}" />
</Rectangle.Fill>
</Rectangle>
What I need to do is let "appbar_add" be a value from a property on my ViewModel -- the Icon
property above.
The resources are in a ResourceDictionary in a separate file (Icon.xaml) and look like the following:
<Canvas x:Key="appbar_add" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="38" Height="38" Canvas.Left="19" Canvas.Top="19" Stretch="Fill" Fill="{DynamicResource BlackBrush}" Data="F1 M 35,19L 41,19L 41,35L 57,35L 57,41L 41,41L 41,57L 35,57L 35,41L 19,41L 19,35L 35,35L 35,19 Z "/>
</Canvas>
You can use a converter to do the work. refer the below code. I have two style to make the + symbol in red color or black color in Icon.xaml.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas x:Key="appbar_add_Black" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="38" Height="38" Canvas.Left="19" Canvas.Top="19" Stretch="Fill" Fill="Black" Data="F1 M 35,19L 41,19L 41,35L 57,35L 57,41L 41,41L 41,57L 35,57L 35,41L 19,41L 19,35L 35,35L 35,19 Z "/>
</Canvas>
<Canvas x:Key="appbar_add_Red" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="38" Height="38" Canvas.Left="19" Canvas.Top="19" Stretch="Fill" Fill="Red" Data="F1 M 35,19L 41,19L 41,35L 57,35L 57,41L 41,41L 41,57L 35,57L 35,41L 19,41L 19,35L 35,35L 35,19 Z "/>
</Canvas>
</ResourceDictionary>
Refer the View code.
<Window.Resources>
<local:IconConverter x:Key="conv"/>
</Window.Resources>
<Grid>
<Rectangle Width="20" Height="20">
<Rectangle.Fill>
<VisualBrush Visual="{Binding Icon,Converter={StaticResource conv}}" />
</Rectangle.Fill>
</Rectangle>
</Grid>
ViewModel
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new CommandViewModel("Red");
}
}
public class CommandViewModel :INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public CommandViewModel(string icon)
{
Icon = icon;
}
private string icon;
public string Icon
{
get { return icon; }
set { icon = value; }
}
}
class IconConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string str = (string)value;
ResourceDictionary myResourceDictionary = new ResourceDictionary();
myResourceDictionary.Source =
new Uri("Icon.xaml",
UriKind.Relative);
if (str.Equals("Black"))
{
return myResourceDictionary["appbar_add_Black"];
}
else
{
return myResourceDictionary["appbar_add_Red"];
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
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