2015-10-18 44 views
1

當我嘗試從代碼後面的列表中綁定靜態資源的名稱時遇到很大問題。從列表的值作爲StaticResource綁定字符串

public IDictionary<int, Menuitem> Categories = new Dictionary<int, Menuitem>(); 
Categories.Add(1, new Menuitem() { Name = "Menu1", Image = "Menu1Resource" }); 
list.ItemsSource = Categories; 

在XAML我

<Page.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="Resources/Icons.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Page.Resources> 

,我想結合這樣

<ListView Padding="20 0" Grid.Row="1" x:Name="list" > 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <Border Background="#53921D" Margin="0 0 0 10" Padding="15"> 
         <Grid> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="1*"/> 
           <ColumnDefinition Width="9*"/> 
          </Grid.ColumnDefinitions> 
          <Image Source="{StaticResource ResourceKey={Binding Value.Image}}"/> 
          <TextBlock Grid.Column="1" Foreground="White" Text="{Binding Value.Name}" HorizontalAlignment="Center" FontSize="30" VerticalAlignment="Center"/> 
         </Grid> 
        </Border> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
      <ListView.ItemContainerStyle> 
       <Style TargetType="ListViewItem"> 
        <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
       </Style> 
      </ListView.ItemContainerStyle> 
</ListView> 

綁定到TextBlock的效果很好,但對圖像源沒有。 當我綁定到圖像源像

Source="{StaticResource Menu1Resource}" 

它的工作太多,但我想從列表自動綁定。 任何人都可以給我任何提示來解決這個問題嗎?)

+0

你能告訴你有什麼參考資料/ Icons.xaml?有圖像或某些矢量(路徑)也許嗎? – marcinax

+0

+0

將本地資源(文件)中的圖像作爲BitmapImage存儲在xaml資源中的原因是什麼?您可以將資源添加爲模型的Uri,而無需額外的BitmapImages和轉換器。就像 [here](http://www.geekchamp.com/tips/data-binding-images-in-windows-phone)。 – marcinax

回答

1

在這一行:

Categories.Add(1, new Menuitem() { Name = "Menu1", Image = "Menu1Resource" }); 

你設置可能獲取ResourceKey Menu1Resource於形象思維,你會得到一個Image對象。

這樣做:

Categories.Add(1, new Menuitem() { Name = "Menu1", Image = _getImgFromResKey("Menu1Resource") }); 

Image _getImgFromResKey(string key) 
{ 
    //access resource from res dictionary 
} 

最後<Image Source="{Binding Value.Image}"/>

How to get resource from Res Dictionary

1

因爲我可以理解的問題是基於viewmodel數據綁定動態地創建圖像。 這裏有幾種解決方案:

  1. 您可以更改菜單項模型的圖像屬性格式是一個BitmapImage的, ,並使用在視圖模型創建URI路徑的情況下此BitmapImage的。

    private void Load(object o) 
    { 
        var name = _mFileProvider.GetFileName(); 
        if(string.IsNullOrEmpty(name)) return; 
        ImageSourceBmp = null; 
        ZoomOriginal(); 
        ImageSourceBmp = new BitmapImage(new Uri(name)); 
    } 
    
    public BitmapImage ImageSourceBmp 
    { 
        get { return _imageSourceBmp; } 
        set 
        { 
         _imageSourceBmp = value; 
         OnPropertyChanged(); 
        } 
    } 
    
  2. 您可以創建轉換路徑中使用一些IValueConverter實施<Image Source="{Binding Value.Image, Converter={StaticResource Path2ImageConverter}}"></Image>從視圖模型的int ImageSourse接收。

問候,

+0

你的意思是,我必須從資源文件獲取Uri到viewmodel,然後直接綁定到圖像? –

+0

@DominikMiedziński是的。 – Ilan

1

在這種情況下,最簡單的方法是在你的菜單項只使用相對URI(像article我上述評論發送)。你可以把工廠變成共享,並用它在W8.1和WP8.1項目創建分類收集:

public class MenuItem 
{ 
    public string Name { get; set; } 

    public Uri ImageUri { get; set; } 
} 

public class CategoriesFactory 
{ 
    public static IDictionary<int, MenuItem> GetCategories() 
    { 
     var categories = new Dictionary<int, MenuItem>(); 

     categories.Add(1, new MenuItem() { Name = "Menu1", ImageUri = new Uri("Icons/image.png", UriKind.RelativeOrAbsolute) }); 

     //add more categories 

     return categories; 
    } 
} 

和直接綁定:

<Image Source="{Binding Value.ImageUri}"/> 

認沽菜單項爲共享太。

注意:這只是樣品,它可以用很多方式解決,但它應該工作。希望它有幫助;)

1

StaticResource只有屬性ResourceKey但這不是一個DependencyProperty,所​​以你不能在這裏使用綁定。這裏的來源當然是來自您的視圖模型(Value.Image),但該來源不能直接用於圖像的Source屬性。這意味着我們需要在這裏使用一些Converter。這可能只是一個單向轉換器,用於將輸入Value.Image轉換爲實際的圖像源。轉換器應作爲視圖模型中的屬性公開。應該有一些服務來幫助通過ResourceKey找到實際的圖像源。這裏是你的代碼應該遵循:

public interface IFindResourceService { 
    object FindResource(object resourceKey); 
} 
public class FindResourceService : IFindResourceService { 
    FrameworkElement _element; 
    public FindResourceService(FrameworkElement startElement){ 
     _element = startElement; 
    } 
    public object FindResource(object resourceKey){ 
     return _element.FindResource(resourceKey); 
    } 
} 

//the converter 
public class ResourceKeyToResourceConverter : IValueConverter { 
    public IFindResourceService FindResourceService {get;set;} 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture){ 
     if(FindResourceService == null) return null; 
     return FindResourceService.FindResource(value); 
    } 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){ 
     throw new NotImplementedException(); 
    } 
} 

//your view-model, suppose it inherits from some base view-model 
//or implements INotifyPropertyChanged directly ... 
public class ViewModel : BaseVM { 
    public ViewModel(IFindResourceService _service){ 
     ResourceKeyToResource.FindResourceService = _service;    
    } 
    public static ResourceKeyToResourceConverter ResourceKeyToResource = new ResourceKeyToResourceConverter(); 
    //... define other properties, members for your view-model normally 
    //... 
} 

當初始化視圖模型,你應該使用構造函數接受IFindResourceService類型的服務,在這種情況下,你應該有機會獲得一些FrameworkElement這是在仍然較低可視樹相比,你聲明的靜態資源,我假設ListBox可用於構建FindResourceService這裏:

public MainWindow(){ 
    InitializeComponent(); 
    var vm = new ViewModel(new FindResourceService(list)); 
    DataContext = vm; 
} 

現在XAML中,您需要設置綁定的ConverterImage到的靜態屬性視圖模式L:

<Image Source="{Binding Value.Image, 
       Converter={x:Static local:ViewModel.ResourceKeyToResource}}"/> 

我假設你把ViewModel在一個命名空間,並宣佈在XAML,作爲local