wpf 从 ViewModel 绑定图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15430374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:06:26  来源:igfitidea点击:

Bind Image from ViewModel

wpfimagemvvm

提问by MrFox

I'm using a XamDataTree and I need the node icons to have different images for every type of node. I tried asking this on Infragistics, but we don't understand each other :(

我正在使用 XamDataTree 并且我需要节点图标来为每种类型的节点提供不同的图像。我试着在 Infragistics 上问这个问题,但我们彼此不了解:(

Also the problem really has nothing to do with their control anymore, it's about how to get an image stored in the model to show. Yes this is against the principles of MVVM, but this is the only workable way of showing the images.

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

Note: I have a workaround, use a Label to specify the node contents and put a horizontal stackpanel in it that has the image and node text in it. But this is crappy, I want the XamDataGrid object to show the image.

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

There are 28 different images to show here, some of which are created dynamically. So I don't want to make a ton of different templates that load the images by file path and then use different templates.

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

The XamDataTree, I also tried specifying the binding with Element name or !. I'm trying to load the image directly from the model or through a DataTemplate:

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>

The model that I use, the image source value is set elsewhere:

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

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

Edit: I tried loading the images directly from files into a BitmapImage, then storing them in the model, din't work. When using higher debugging level messaging it posts messages in the output that the databinding cannot find the corrosponding property. So the problem is most likely in my data binding.

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

回答by Jehof

Another solution would be to use a converter and the type Stream for your property NodeImage.

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

Converter:

转换器:

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

Property:

财产:

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

XAML:

XAML:

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

回答by Jehof

Change your property NodeImageto type stringand return the path of the Image. The rest is done by the Image and the converter classes that convert your path to a ImageSource.

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

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