C# 将列表值中的字符串绑定为StaticResource
当我试图从代码隐藏中的列表中绑定静态资源的名称时,我遇到了一个大问题C# 将列表值中的字符串绑定为StaticResource,c#,wpf,xaml,windows-phone-8.1,C#,Wpf,Xaml,Windows Phone 8.1,当我试图从代码隐藏中的列表中绑定静态资源的名称时,我遇到了一个大问题 public IDictionary<int, Menuitem> Categories = new Dictionary<int, Menuitem>(); Categories.Add(1, new Menuitem() { Name = "Menu1", Image = "Menu1Resource" }); list.ItemsSource = Categories; 它也在工作,但我想从列表
public IDictionary<int, Menuitem> Categories = new Dictionary<int, Menuitem>();
Categories.Add(1, new Menuitem() { Name = "Menu1", Image = "Menu1Resource" });
list.ItemsSource = Categories;
它也在工作,但我想从列表中自动绑定。
有人能给我一些建议来解决这个问题吗 据我所知,问题在于基于viewmodel数据绑定动态创建图像。 以下是几种解决方案:
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();
}
}
IValueConverter
实现
在图像源中创建从viewmodel接收的转换路径关于,据我所知,问题是基于viewmodel数据绑定动态创建图像。 以下是几种解决方案:
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();
}
}
IValueConverter
实现
在图像源中创建从viewmodel接收的转换路径关于,在这种情况下,最简单的解决方案是在菜单项中只使用相对Uri(就像我在上面的评论中发送的那样)。您可以将factory放入共享,并在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;
}
}
公共类菜单项
{
公共字符串名称{get;set;}
公共Uri ImageUri{get;set;}
}
公共类分类工厂
{
公共静态IDictionary GetCategories()
{
var categories=新字典();
categories.Add(1,new-MenuItem(){Name=“Menu1”,ImageUri=new-Uri(“Icons/image.png”,UriKind.RelativeOrAbsolute)});
//添加更多类别
退货类别;
}
}
并直接绑定:
<Image Source="{Binding Value.ImageUri}"/>
将菜单项也放入共享
注意:这只是一个示例,可以用多种方法解决,但应该可以。希望有帮助;) 在这种情况下,最简单的解决方案是在Menuitem中只使用相对Uri(就像我在上面的评论中发送的那样)。您可以将factory放入共享,并在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;
}
}
公共类菜单项
{
公共字符串名称{get;set;}
公共Uri ImageUri{get;set;}
}
公共类分类工厂
{
公共静态IDictionary GetCategories()
{
var categories=新字典();
categories.Add(1,new-MenuItem(){Name=“Menu1”,ImageUri=new-Uri(“Icons/image.png”,UriKind.RelativeOrAbsolute)});
//添加更多类别
退货类别;
}
}
并直接绑定:
<Image Source="{Binding Value.ImageUri}"/>
将菜单项也放入共享
注意:这只是一个示例,可以用多种方法解决,但应该可以。希望有帮助;)
StaticResource
只有属性ResourceKey
,但这不是从属属性,因此不能在此处使用绑定。这里的源当然来自视图模型(Value.Image),但该源不能直接用于图像的源属性。这意味着我们需要在这里使用一些转换器。这可能只是一个单向转换器,用于将输入的值.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中,您需要将图像
中绑定的转换器
设置为视图模型的静态属性:
<Image Source="{Binding Value.Image,
Converter={x:Static local:ViewModel.ResourceKeyToResource}}"/>
我假设您将ViewModel
放在一个命名空间中,并在XAML中声明为local
。StaticResource
只有属性ResourceKey
,但这不是一个dependencProperty,因此您不能在这里使用绑定。这里的源当然来自视图模型(Value.Image
),但该源不能直接用于图像的源属性。这意味着我们需要在这里使用一些转换器。这可能只是一个单向转换器,用于将输入的值.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中,您需要将图像
中绑定的转换器
设置为视图模型的静态属性:
<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
}
最后是
在这一行中:
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
}
最后是