查看模型图像属性?

发布于 2024-12-11 09:26:36 字数 1895 浏览 0 评论 0原文

我有一个绑定到 TreeView 的视图模型列表,但是这些视图模型代表一个“文件系统”,例如带有“文件”和“文件夹”的数据结构。因此,在我的树视图视图的项目模板中,我有一个应该代表文件夹或文件的图像。

这是我的 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>

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

谢谢, 亚历克斯.

I have a list of view models which I am binding to a TreeView, however these view models are representing a 'file system' like data structure with 'files' and 'folders'. So in the item template on my view for the tree view I have an image which should represent either a folder or a file.

Here is My 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>

So basically I want to know how to bind the source of the image object to my view models.

Thanks,
Alex.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

¢好甜 2024-12-18 09:26:36

我认为最好的方法是使用这样的转换器:

    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 声明并在视图模型中加载,并且仍然可以使其完全可绑定。

I think that the best way to do this is using a converter like this:

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

Then declare an enumeration called NodeType:

enum NodeType
{
    Folder,
    File,
}

In your view model you declare an INotifyPropertyChanged property called NodeType of the enumeration type.

Then in your XAML you declare the converter resource like this:

 <Converters:EnumToResource x:Key="IconConverter">
  <Converters:EnumToResource.EnumMapping>
   <BitmapImage UriSource="\Resources\Folder.png"/>
   <BitmapImage UriSource="\Resources\File.png"/>
  </Converters:EnumToResource.EnumMapping>
 </Converters:EnumToResource>

Finally you bind your property like this:

     <Image Source="{Binding Path=NodeType, Converter={StaticResource ResourceKey=IconConverter}}"/>

This way you do not need to deal with BitmapImage declarations and loading in your view model and you can still make it fully bindable.

只是偏爱你 2024-12-18 09:26:36

在您的视图模型中添加新属性 Icon,即将

public BitmapImage Icon
    {
        get
        {
            return this._icon;
        }

        set
        {
            this._icon = value;
            this.NotifyPropertyChanged("Icon");
        }
    } 

DataTemplate 中的图像源更改为: Source="{Binding Path=Icon}"
并相应地在视图模型中加载图标,即对于文件夹视图模型,使用如下所示:

this.Icon = new BitmapImage(new Uri("/Your_assembly;component/Images/folder.png", UriKind.Relative));

In your view models add new property Icon, i.e.

public BitmapImage Icon
    {
        get
        {
            return this._icon;
        }

        set
        {
            this._icon = value;
            this.NotifyPropertyChanged("Icon");
        }
    } 

change Image's source in DataTemplate to: Source="{Binding Path=Icon}"
and load your icons in view model accordingly, i.e. for folder view model use something like this:

this.Icon = new BitmapImage(new Uri("/Your_assembly;component/Images/folder.png", UriKind.Relative));
相对绾红妆 2024-12-18 09:26:36

我发现这个解决方案非常有趣。在研究过程中,我对原始代码进行了一些适度的改进,我提交这些改进是希望其他人可以受益。

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

I found this solution very interesting. In studying it, I came up with a few modest improvements to the original code, which I submit in hopes someone else may benefit.

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文