我有一个视图模型列表,我绑定到TreeView,但是这些视图模型表示'文件系统',如带有'files'和'folders'的数据结构。因此,在我的树视图视图的项目模板中,我有一个应该代表文件夹或文件的图像。
这是我的XAML:
<StackPanel Orientation="Horizontal">
<!-- Folder Icon -->
<Image Width="15" Height="15" Stretch="Fill" Source="\Resources\Folder.png"></Image>
<Grid>
<!-- Folder Name -->
<Label Content="{Binding Path=FolderName}">
<!-- Force Selection on Right Click -->
<ACB:CommandBehaviourCollection.Behaviours>
<ACB:BehaviourBinding Event="PreviewMouseRightButtonDown" Command="{Binding Path=MainModel.SelectTreeViewItem}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}"></ACB:BehaviourBinding>
</ACB:CommandBehaviourCollection.Behaviours>
</Label>
<!-- Folder Name Editor -->
<StackPanel Name="FolderEditor" Orientation="Horizontal" Visibility="Collapsed">
<TextBox Text="{Binding Path=FolderName}" Width="130"></TextBox>
<Button Content="Ok" Command="{Binding Path=RenameFolder}" CommandParameter="{Binding ElementName=FolderEditor}"></Button>
</StackPanel>
</Grid>
</StackPanel>
所以基本上我想知道如何将图像对象的源绑定到我的视图模型。
谢谢, 亚历克斯。
答案 0 :(得分:2)
我认为最好的方法是使用这样的转换器:
public class EnumToResource : IValueConverter
{
public List<object> EnumMapping { get; set; }
public EnumToResource()
{
EnumMapping = new List<object>();
}
public virtual object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int adjustment = 0;
if (parameter != null && !Int32.TryParse(parameter.ToString(), out adjustment))
{
adjustment = 0;
}
if (value == null) return this.EnumMapping.ElementAtOrDefault(0);
else if (value is bool)
return this.EnumMapping.ElementAtOrDefault(System.Convert.ToByte(value) + adjustment);
else if (value is byte)
return this.EnumMapping.ElementAtOrDefault(System.Convert.ToByte(value) + adjustment);
else if (value is short)
return this.EnumMapping.ElementAtOrDefault(System.Convert.ToInt16(value) + adjustment);
else if (value is int)
return this.EnumMapping.ElementAtOrDefault(System.Convert.ToInt32(value) + adjustment);
else if (value is long)
return this.EnumMapping.ElementAtOrDefault(System.Convert.ToInt32(value) + adjustment);
else if (value is Enum)
return this.EnumMapping.ElementAtOrDefault(System.Convert.ToInt32(value) + adjustment);
return this.EnumMapping.ElementAtOrDefault(0);
}
public virtual object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后声明一个名为NodeType的枚举:
enum NodeType
{
Folder,
File,
}
在视图模型中,声明一个名为NodeType的INotifyPropertyChanged属性。
然后在你的XAML中声明转换器资源如下:
<Converters:EnumToResource x:Key="IconConverter">
<Converters:EnumToResource.EnumMapping>
<BitmapImage UriSource="\Resources\Folder.png"/>
<BitmapImage UriSource="\Resources\File.png"/>
</Converters:EnumToResource.EnumMapping>
</Converters:EnumToResource>
最后你绑定你的属性:
<Image Source="{Binding Path=NodeType, Converter={StaticResource ResourceKey=IconConverter}}"/>
这样您就不需要在视图模型中处理BitmapImage声明和加载,您仍然可以使它完全可绑定。
答案 1 :(得分:0)
在您的视图模型中添加新属性Icon,即
public BitmapImage Icon
{
get
{
return this._icon;
}
set
{
this._icon = value;
this.NotifyPropertyChanged("Icon");
}
}
将DataTemplate中Image的源更改为:Source =“{Binding Path = Icon}” 并相应地在视图模型中加载您的图标,即文件夹视图模型使用如下内容:
this.Icon = new BitmapImage(new Uri("/Your_assembly;component/Images/folder.png", UriKind.Relative));
答案 2 :(得分:0)
我发现这个解决方案非常有趣。在研究它时,我对原始代码进行了一些适度的改进,我希望其他人可以从中受益。
public class ResourceIndexer : IValueConverter
{
// initialized via xaml
public List<object> Resources { get; set; }
public ResourceIndexer()
{
Resources = new List<object>();
}
public virtual object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
int index = ConvertToInt( value );
if( parameter != null )
{
index += ConvertToInt( parameter );
}
var selected = this.Resources.ElementAtOrDefault( index );
return selected;
}
public static int ConvertToInt( object value )
{
if( value == null )
{
throw new ArgumentNullException();
}
int index = 0;
if( value is bool || value is Enum
|| value is byte || value is sbyte
|| value is short || value is ushort
|| value is int || value is uint
|| value is long || value is ulong
|| value is char
)
{
index = System.Convert.ToInt32( value );
}
else if( value is string )
{
if( !int.TryParse( (string)value, out index ) )
throw new ArgumentOutOfRangeException( "" );
// else the conversion went into index
}
else
{
throw new NotSupportedException( $"cannot index non-integral type ({value.GetType().Name}" );
}
return index;
}
public virtual object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
throw new NotImplementedException();
}
}