【问题标题】:Bind Image from ViewModel从 ViewModel 绑定图像
【发布时间】:2013-03-15 10:47:02
【问题描述】:

我正在使用 XamDataTree,我需要节点图标为每种类型的节点提供不同的图像。我试过asking this on Infragistics,但我们彼此不了解:(

此外,问题实际上与他们的控制无关,而是关于如何获取存储在模型中的图像来显示。是的,这违反了 MVVM 的原则,但这是显示图像的唯一可行方式。

注意:我有一个解决方法,使用标签来指定节点内容并在其中放置一个水平堆栈面板,其中包含图像和节点文本。但这很糟糕,我希望 XamDataGrid 对象显示图像。

这里展示了 28 张不同的图片,其中一些是动态创建的。所以我不想制作大量不同的模板,通过文件路径加载图像,然后使用不同的模板。

XamDataTree,我还尝试使用元素名称或! 指定绑定。 我正在尝试直接从模型或通过 DataTemplate 加载图像:

<ig:XamDataTree
    ScrollViewer.CanContentScroll="True"
    ItemsSource="{Binding Model}"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    NodeLineVisibility="Visible"
    >
    <ig:XamDataTree.Resources>
        <DataTemplate x:Key="nodeImage" >
            <Image Source="{Binding Path=NodeImage}" />
        </DataTemplate>
    </ig:XamDataTree.Resources>
    <ig:XamDataTree.GlobalNodeLayouts>
        <ig:NodeLayout
            ExpandedIconTemplate="{StaticResource nodeImage}"
            CollapsedIconTemplate="{Binding NodeImage}"
            Key="Children"
            DisplayMemberPath="Name"
            TargetTypeName="Model"
            >
        </ig:NodeLayout>
    </ig:XamDataTree.GlobalNodeLayouts>
</ig:XamDataTree>

我使用的模型,图片源值在别处设置:

public class Model
{
    /// <summary>
    /// Image representing the type of node this is.
    /// </summary>
    public ImageSource NodeImage
    {
        get
        {
            return this.nodeImage;
        }
        set
        {
            this.nodeImage = value;
            this.OnPropertyChanged("NodeImage");
        }
    }

    /// <summary>
    /// Controls will bind their attributes to this event handler.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Fire an event alerting listners a property changed.
    /// </summary>
    /// <param name="name">Name of the property that changed.</param>
    public void OnPropertyChanged(string name)
    {
        // Check whether a control is listening.
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

编辑: 我尝试将图像直接从文件加载到 BitmapImage 中,然后将它们存储在模型中,但不起作用。当使用更高的调试级别消息传递时,它会在输出中发布数据绑定找不到对应属性的消息。所以问题很可能出在我的数据绑定上。

【问题讨论】:

    标签: wpf image mvvm


    【解决方案1】:

    另一种解决方案是为您的属性 NodeImage 使用转换器和 Stream 类型。

    转换器:

    public class StreamToImageConverter : IValueConverter {
      public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            var imageStream = value as System.IO.Stream;
            if (imageStream != null)) {
                System.Windows.Media.Imaging.BitmapImage image = new System.Windows.Media.Imaging.BitmapImage();
                image.SetSource(imageStream );
                return image;
            }
            else {
               return null;
            }
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            throw new NotImplementedException();
        }
    }
    

    属性:

    private Stream _imageStream;
    public Stream NodeImage
    {
        get
        {
            return _imageStream;
        }
        set
        {
            _imageStream= value;
            this.OnPropertyChanged("NodeImage");
        }
    }
    

    XAML:

    <Grid>
       <Grid.Resources>
         <local:StreamToImageConverter x:Name="imageConverter"/>
       </Grid.Resources>
       <Image Source="{Binding Path=NodeImage, Converter={StaticResource imageConverter}" />
     </Grid>
    

    【讨论】:

    • 如果你有一个 Stream 你可以直接绑定到 Image.Source 属性。无需转换器。
    【解决方案2】:

    将您的属性NodeImage 更改为输入string 并返回图像的路径。其余部分由 Image 和将您的路径转换为 ​​ImageSource 的转换器类完成。

    private string _imagePath;
    public string NodeImage
    {
        get
        {
            return _imagePath;
        }
        set
        {
            _imagePath = value;
            this.OnPropertyChanged("NodeImage");
        }
    }
    

    【讨论】:

    • 部分图片是动态创建的。
    • 动态是什么意思?您是否将它们存储在文件系统中?也许你应该更新你的答案图像是如何创建的
    • 我结合不同的图像来创建新的图像来展示。这可以提前完成。但这不会导致每次都从磁盘加载每个图像吗?与其从磁盘加载图像一次,不如构建另一个图像并在许多地方同时使用它们。
    • @MrFox 试试看,我认为这不是一个真正的性能问题。
    • 返回一个 URI,而不是一个字符串。以新的 Uri("/ApplicationCatalogModule;component/Images/Applications-icon.png",UriKind.Relative) 为例。
    猜你喜欢
    • 2018-12-18
    • 2017-05-01
    • 1970-01-01
    • 2015-03-21
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多