繁体   English   中英

将列表值中的字符串绑定为StaticResource

[英]Binding string from value of list as 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效果很好,但绑定到Image Source却不行。 当我像这样绑定到图像源时

Source="{StaticResource Menu1Resource}"

它也工作,但我想从列表中自动绑定。 谁能给我任何解决这个问题的技巧?;)

据我了解,问题是基于viewmodel数据绑定动态创建Image。 以下是几种解决方案:

  1. 您可以将Menuitem模型的图像属性更改为BitmapImage,并使用在viewmodel中创建的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>创建从ViewModel到ImageSourse的转换路径。

问候,

在这种情况下,最简单的解决方案是在Menuitem中仅使用相对Uri(就像我在上面评论中发送的文章中一样)。 您可以将工厂共享 ,并在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}"/>

也将MenuItem放入共享

注意:这只是示例,可以通过多种方式解决,但应该可以。 希望能帮助到你 ;)

StaticResource仅具有ResourceKey属性,但这不是DependencyProperty,因此您不能在此处使用Binding。 这里的源当然来自您的视图模型( Value.Image ),但是该源不能直接用于Image的Source属性。 这意味着我们需要在这里使用一些Converter。 这可以是将输入Value.Image转换为实际图像源的单向转换器。 Converter应该在视图模型中作为属性公开。 应该有一些服务可以帮助您通过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 ,与您声明的静态资源相比,该FrameworkElement在可视树中仍然较低,我认为ListBox可以用于在此处构造FindResourceService

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

现在,在XAML中,您需要将“ Image中的绑定Converter ”设置为视图模型的静态属性:

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

我假设您将ViewModel放在命名空间中,并在XAML中声明为local

在这一行:

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

您可能将ResourceKey Menu1Resource设置为Image,以为您将获得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}"/>

如何从Res词典中获取资源

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM