2013-02-21 13 views
7

Mam aplikację WPF, która musi przekazać użytkownikowi informacje zwrotne na temat stanu wewnętrznego. Projekt ma mieć trzy obrazy, nazwać je czerwonymi, żółtymi i zielonymi. Jeden z tych obrazów będzie wyświetlany w czasie zależnym od stanu. Oto punkty:Jak zmienić źródło obrazu dynamicznie z opóźnionego kodu w WPF z obrazem w Właściwości. Źródła?

  • Trzy obrazy są w Properties.Resources w opóźnieniem kodu
  • tylko jeden z obrazów zostanie pokazany na raz.
  • Zmiana stanu pochodzi z procesu w kodzie źródłowym, a nie od użytkownika.
  • Chciałbym związać kontrolę obrazu, aby móc zmienić obraz z opóźnieniem kodu.

Jestem zakładając Muszę przetwornik obrazu, aby zmienić obraz JPG do źródła obrazu, takie jak:


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

wolałbym konwertować obrazy raz podczas inicjalizacji i zachowaj listę źródeł obrazów. Zakładam, że również będę potrzebował właściwość zależność powiązać kontrolę, ale nie jestem pewien, w jaki sposób ustawić, że się z tej listy źródeł obrazu:


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

Odpowiedz

31

chociaż źródło obrazu w projekcie WPF generuje właściwość System.Drawing.Bitmap w Resources.Designer.cs, można bezpośrednio utworzyć BitmapImage z tego zasobu. Musisz tylko ustawić Build Action pliku obrazu na Resource (zamiast domyślnego None).

Jeśli masz plik Red.jpg w folderze Resources w programie Visual Studio Project, utworzenie pliku BitmapImage będzie wyglądać tak, jak pokazano poniżej. Używa WPF Pack Uri.

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

Jeśli masz Image kontroli deklarowanych gdzieś w XAML tak:

<Image x:Name="image"/> 

można po prostu ustawić właściwość obrazu Source do BitmapImage w kodzie za:

image.Source = bitmap; 

Jeśli wolisz ustawićWłaściwośćwiążąc można utworzyć właściwość string, która zwraca identyfikator URI obrazu. Ciąg zostanie automatycznie przekonwertowany na BitmapImage przez wbudowany TypeConverter w 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); } 
    } 
} 

W XAML byś wiążą się z tego mienia tak:

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

Oczywiście można także zadeklarować właściwość być typu 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); } 
} 

i bindować w ten sam sposób:

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

Teraz można wstępnie załadować swoje zdjęcia i umieść je na własność, ile potrzeba:

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: Po tym wszystkim, twoje zdjęcia nie muszą być zasoby w projekcie Visual Studio. Możesz po prostu dodać folder projektu, umieścić pliki obrazów w tym folderze i ustawić ich działanie Build na Resource. Jeśli na przykład wywołasz folder Images, identyfikator URI będzie wynosił pack://application:,,,/Images/Red.jpg.

+0

Clemens Skałasz! To była fantastyczna, kompleksowa i łatwa do zrozumienia odpowiedź. Skłaniam się do skorzystania z opcji wiązania, ale w moim przypadku pierwsza opcja ustawienia źródła w kodzie źródłowym jest po prostu zbyt elegancka. Jedynym problemem jest to, że nie mogłem go uruchomić z plikami png. Miałem nadzieję na przejrzyste tło. Czy powinien działać z plikami png? Czy robię coś złego, czy też nie są one obsługiwane? – dtaylor

+0

Powinno to również działać z plikami PNG. Może nie powinieneś dodawać ich jako zasobów do twojego projektu (zobacz moją edycję). Po prostu utwórz pliki za pomocą ulubionego narzędzia obrazu i dodaj je do folderu w projekcie. Zobacz [tutaj] (http://meta.stackexchange.com/a/5235) na temat akceptacji. – Clemens

+0

Clemens, Znowu podałeś jasną i zwięzłą odpowiedź! Plik PNG działa świetnie, kiedy po prostu umieszczam go w folderze i robię go jako zasób, zamiast dodawać go jako właściwości .resource w projektancie zasobów. Stukrotne dzięki. – dtaylor

Powiązane problemy