Как динамически изменить Источник изображения из кода в WPF с изображением в свойствах.Ресурсы?

у меня есть приложение WPF, которое должно предоставлять обратную связь пользователю о внутреннем состоянии. Дизайн должен иметь три изображения, назовите их красным, желтым и зеленым. Одно из этих изображений будет отображаться одновременно в зависимости от состояния. Вот пункты:

  • три изображения находятся в свойствах.Ресурсы в коде
  • одновременно будет отображаться только одно из изображений.
  • изменение состояния происходит от процесса в коде и не от пользователя.
  • Я хотел бы связать элемент управления изображением, чтобы я мог изменить изображение из кода.

Я предполагаю, что мне понадобится конвертер изображений, чтобы изменить изображение 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); }
    }

1 ответов


хотя ресурс изображения в проекте WPF генерирует System.Drawing.Bitmap в собственность Resources.Designer.cs, вы можете сразу создать BitmapImage из этого ресурса. Вам нужно только установить Создать Действие из файла изображения в Resource (вместо None).

если у вас есть файл Red.jpg на Resources папка вашего проекта Visual Studio, создающая BitmapImage будет выглядеть как показано ниже. Он использует в WPF пакет Ури.

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

если у вас Image control объявлен где-то в XAML следующим образом:

<Image x:Name="image"/>

вы можете просто установить Source свойство изображения для вашего растрового изображения в коде позади:

image.Source = bitmap;

в случае, если вы предпочитаете, чтобы установить Source свойство путем привязки вы можете создать string свойство, возвращающее URI изображения. Строка будет автоматически преобразована в BitmapImage встроенный TypeConverter в WPF.

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;

UPDATE: в конце концов, ваши изображения не должны быть ресурсами в проект Visual Studio. Вы можете просто добавить папку проекта, поместить файлы изображений в эту папку и установить их действие сборки в Resource. Если, например, вы вызываете папку Images, URI будет pack://application:,,,/Images/Red.jpg.