查看模特图片属性?

时间:2011-10-24 02:36:49

标签: .net wpf xaml mvvm .net-4.0

我有一个视图模型列表,我绑定到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>

所以基本上我想知道如何将图像对象的源绑定到我的视图模型。

谢谢, 亚历克斯。

3 个答案:

答案 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();
    }
}