2015-04-01 45 views
4

這不是MahApps.Metro特定的,但恰好是我正在使用的。我有一組ViewModel,它們具有string屬性,表示從資源XAML文件使用哪個圖標。如何爲DynamicResource使用ViewModel變量?

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將結束是像從MahApps.Metro.Resources 「appbar_add」。這些在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> 

我需要做的是讓什麼「appbar_add」是一個值從屬性在我的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

有用的鏈接:http://stackoverflow.com/questions/20564862/binding-to-resource-key-wpf – dugas 2015-04-01 17:59:11

回答

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(); 
    } 
} 
+0

這給出了一個錯誤,無論是因爲圖標是一個字符串(而不是圖像),或因爲我需要在這種情況下引用不同的資源。 ''TargetDefaultValueConverter'轉換器無法轉換值'<圖標的值>'和'IOException:'System.IO.IOException:找不到資源'<圖標的值>'。當它直接用於我最初作爲VisualBrush的Visual('')發佈的代碼中時,該值工作得很好。如果需要,我可以提供更多細節。 – 2015-04-01 19:52:34

+0

你想給圖像的完整路徑? – 2015-04-01 19:55:35

+0

不,只是它在Icons.xaml文件中的名稱。 「appbar_add」,在這種情況下。作爲StaticResource可以正常工作,但作爲Image Source失敗。我應該嘗試更復雜的路徑引用嗎? – 2015-04-01 19:57:08

2

由於加尼甚說,你可以使用一個轉換器。我只是從建議的一個小改變了轉換器:

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的是在資源部分註冊轉換器:

<UserControl.Resources> 
     <vc:FindResourceFromString x:Key="FindResourceFromStringConverter" /> 
</UserControl.Resources> 

這裏假設您有一個名爲vc的轉換器。