这不是MahApps.Metro特有的,但恰好是我正在使用的。我有一组ViewModel,它们具有string
属性,表示从资源XAML文件中使用哪个图标。
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
最终将成为" appbar_add"来自MahApps.Metro.Resources。这些是在Icons.xaml文件中定义的。
如何在我的ItemTemplate
中写下这样,以便显示正确的资源。我要么在执行时遇到错误(不是在编辑/构建时),要么我没有得到任何图标。
"没有图标" XAML看起来像这样:
<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>
我导致错误的尝试是使用StaticResource
,我认为这是根本不正确的。
我应该如何引用Icon
属性作为我想要的资源的名称?
修改
我们要求提供更多代码,因此以下是 工作的示例:
<Rectangle Width="20" Height="20">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource appbar_add}" />
</Rectangle.Fill>
</Rectangle>
我需要做的是让#34; appbar_add&#34;是我的ViewModel上的属性值 - 上面的Icon
属性。
资源位于单独文件(Icon.xaml)中的ResourceDictionary中,如下所示:
<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>
答案 0 :(得分:2)
您可以使用转换器来完成工作。请参考以下代码。我有两种风格可以在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>
请参阅查看代码。 视图模型
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();
}
}
答案 1 :(得分:2)
正如Ganesh所说,你可以使用转换器。我只想改变一下建议的转换器:
public class FindResourceFromString: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null) return Application.Current.FindResource((string) value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
这将获取字符串并返回资源(来自资源字典)。如果找不到具有字符串名称的资源,您可能希望转换器返回占位符图标。
XAML看起来像这样:
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Width="20" Height="20">
<Rectangle.Fill>
<VisualBrush Visual="{Binding Icon, Converter={StaticResource FindResourceFromStringConverter}}" />
</Rectangle.Fill>
</Rectangle>
<TextBlock Margin="15,6">
<Hyperlink Command="{Binding Path=Command}">
<TextBlock Text="{Binding Path=DisplayName}" />
</Hyperlink>
</TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
您需要在ItemsControl所在的用户控件或窗口的resources部分注册转换器:
<UserControl.Resources>
<vc:FindResourceFromString x:Key="FindResourceFromStringConverter" />
</UserControl.Resources>
这假设您可以从名为 vc 的命名空间中获得转换器。