【问题标题】:How do I change an image source dynamically from code-behind in WPF with an image in Properties.Resources?如何使用 Properties.Resources 中的图像从 WPF 中的代码隐藏动态更改图像源?
【发布时间】:2013-02-21 15:55:10
【问题描述】:

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

  • 这三个图像位于代码隐藏的 Properties.Resources 中
  • 一次只会显示一张图片。
  • 状态更改来自代码隐藏中的进程,而不是来自用户。
  • 我想绑定一个图像控件,以便我可以从代码隐藏中更改图像。

我假设我需要一个图像转换器来将 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();
    }
}

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


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

【问题讨论】:

    标签: wpf imagesource


    【解决方案1】:

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

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

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

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

    <Image x:Name="image"/>
    

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

    image.Source = bitmap;
    

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

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

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

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

    当然你也可以将属性声明为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); }
    }
    

    并以同样的方式绑定:

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

    现在您可以根据需要预加载图片并放入属性中:

    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;
    

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

    【讨论】:

    • 克莱门斯 你摇滚!这是一个很棒的、全面的、易于理解的回应。我很想使用绑定选项,但在我的情况下,在代码隐藏中设置源的第一个选项太优雅了。唯一的问题是我无法让它与 png 文件一起使用。我希望有一个透明的背景。它应该与png文件一起使用吗?我只是做错了什么,还是它们不受支持?
    • 这应该也适用于 PNG 文件。也许您不应该将它们作为资源添加到您的项目中(请参阅我的编辑)。只需使用您喜欢的图像工具创建文件并将它们添加到项目中的文件夹即可。有关接受,请参阅here
    • Clemens,您再次提供了清晰简洁的答案!当我只是将 PNG 文件放在文件夹中并将其作为资源而不是将其添加为资源设计器中的 properties.resource 时,PNG 文件效果很好。谢谢一百万。
    猜你喜欢
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    相关资源
    最近更新 更多