如何使用 Properties.Resources 中的图像从 WPF 中的代码隐藏动态更改图像源?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15006618/
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-08 23:41:22  来源:igfitidea点击:

How do I change an image source dynamically from code-behind in WPF with an image in Properties.Resources?

wpfimagesource

提问by dtaylor

I have a WPF application that needs to provide feedback to the user about an internal state. The design is to have three images, call them Red, Yellow, and Green. One of these images will be displayed at a time depending on the state. Here are the points:

我有一个 WPF 应用程序,需要向用户提供有关内部状态的反馈。设计是有三个图像,分别称为红色、黄色和绿色。这些图像之一将根据状态一次显示。以下是要点:

  • The three images are in Properties.Resources in the code-behind
  • Only one of the images will be shown at a time.
  • The state change comes from a process in code-behind and not from the user.
  • I would like to bind an image control so that I can change the image from code-behind.
  • 三张图片在代码隐藏的Properties.Resources中
  • 一次只会显示其中一张图像。
  • 状态更改来自代码隐藏中的进程,而不是来自用户。
  • 我想绑定一个图像控件,以便我可以从代码隐藏中更改图像。

I'm assuming I'll need an image converter to change the JPG image to an image source such as:

我假设我需要一个图像转换器来将 JPG 图像更改为图像源,例如:



[ValueConversion(typeof(System.Drawing.Bitmap), typeof(ImageSource))]
public class BitmapToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var bmp = value as System.Drawing.Bitmap;
        if (bmp == null)
            return null;
        return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    bmp.GetHbitmap(),
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}


I'd prefer to convert the images once during initialization and keep a list of Image sources. I'm also assuming I'll need a dependency property to bind the control to, but I'm not sure how to set that up with this list of image sources:

我更喜欢在初始化期间转换图像并保留图像源列表。我还假设我需要一个依赖属性来绑定控件,但我不确定如何使用以下图像源列表进行设置:



    // Dependancy Property for the North Image
    public static readonly DependencyProperty NorthImagePathProperty
        = DependencyProperty.Register(
            "NorthImagePath",
            typeof(ImageSource),
            typeof(MainWindow),
            new PropertyMetadata("**Don't know what goes here!!!**"));

    // Property wrapper for the dependancy property
    public ImageSource NorthImagePath
    {
        get { return (ImageSource)GetValue(NorthImagePathProperty); }
        set { SetValue(NorthImagePathProperty, value); }
    }

回答by Clemens

Although an image resource in a WPF project generates a System.Drawing.Bitmapproperty in Resources.Designer.cs, you could directly create a BitmapImagefrom that resource. You only need to set the Build Actionof the image file to Resource(instead of the default None).

尽管 WPF 项目中的图像资源在 中生成System.Drawing.Bitmap属性Resources.Designer.cs,但您可以直接BitmapImage从该资源创建。您只需要将图像文件的Build Action设置为Resource(而不是默认的None)。

If you have a file Red.jpgin the Resourcesfolder of your Visual Studio Project, creating a BitmapImagewould look like shown below. It uses a WPF Pack Uri.

如果您的 Visual Studio 项目文件夹中有一个文件Red.jpg,则Resources创建一个BitmapImage如下所示的文件。它使用WPF Pack Uri

var uri = new Uri("pack://application:,,,/Resources/Red.jpg");
var bitmap = new BitmapImage(uri);

If you have an Imagecontrol declared somewhere in XAML like this:

如果您Image在 XAML 中的某处声明了一个控件,如下所示:

<Image x:Name="image"/>

you could simply set the Sourceproperty of the image to your BitmapImage in code behind:

您可以Source在后面的代码中简单地将图像的属性设置为您的 BitmapImage:

image.Source = bitmap;


In case you prefer to set the Sourceproperty by binding you could create a stringproperty that returns the image URI. The string will automatically be converted to a BitmapImageby a built-in TypeConverterin WPF.

如果您更喜欢Source通过绑定来设置属性,您可以创建一个string返回图像 URI的属性。该字符串将BitmapImage通过TypeConverterWPF 中的内置函数自动转换为 a 。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        ImageUri = "pack://application:,,,/Resources/Red.jpg";
    }

    public static readonly DependencyProperty ImageUriProperty =
        DependencyProperty.Register("ImageUri", typeof(string), typeof(MainWindow));

    public string ImageUri
    {
        get { return (string)GetValue(ImageUriProperty); }
        set { SetValue(ImageUriProperty, value); }
    }
}

In XAML you would bind to that property like this:

在 XAML 中,您可以像这样绑定到该属性:

<Image Source="{Binding ImageUri}"/>


Of course you could as well declare the property to be of type ImageSource

当然,您也可以将属性声明为类型 ImageSource

public static readonly DependencyProperty ImageProperty =
    DependencyProperty.Register("Image", typeof(ImageSource), typeof(MainWindow));

public ImageSource Image
{
    get { return (ImageSource)GetValue(ImageProperty); }
    set { SetValue(ImageProperty, value); }
}

and bind in the same way:

并以相同的方式绑定:

<Image Source="{Binding Image}"/>

Now you could pre-load your images and put them into the property as needed:

现在您可以预加载您的图像并根据需要将它们放入属性中:

private ImageSource imageRed =
    new BitmapImage(new Uri("pack://application:,,,/Resources/Red.jpg"));
private ImageSource imageBlue =
    new BitmapImage(new Uri("pack://application:,,,/Resources/Blue.jpg"));
...
Image = imageBlue;


UPDATE: After all, your images do not need to be resources in the Visual Studio project. You could just add a project folder, put the image files into that folder and set their Build Action to Resource. If for example you call the folder Images, the URI would be pack://application:,,,/Images/Red.jpg.

更新:毕竟,您的图像不需要是 Visual Studio 项目中的资源。您可以添加一个项目文件夹,将图像文件放入该文件夹并将其构建操作设置为Resource. 例如,如果您调用文件夹Images,则 URI 将为pack://application:,,,/Images/Red.jpg.