2013-02-21 26 views
7

Tôi có một ứng dụng WPF cần cung cấp phản hồi cho người dùng về trạng thái nội bộ. Thiết kế là có ba hình ảnh, gọi chúng là Đỏ, Vàng và Xanh lục. Một trong những hình ảnh này sẽ được hiển thị tại một thời điểm tùy thuộc vào tiểu bang. Sau đây là các điểm:Làm cách nào để thay đổi nguồn hình ảnh động từ mã-đằng sau trong WPF bằng một hình ảnh trong Properties.Resources?

  • Ba hình ảnh trong Properties.Resources trong code-behind
  • Chỉ có một trong những hình ảnh sẽ được hiển thị tại một thời điểm.
  • Thay đổi trạng thái xuất phát từ quá trình mã hóa phía sau chứ không phải từ người dùng.
  • Tôi muốn liên kết điều khiển hình ảnh để tôi có thể thay đổi hình ảnh từ mã sau.

Tôi giả định tôi sẽ cần một bộ chuyển đổi hình ảnh để thay đổi hình ảnh JPG để một nguồn hình ảnh như:


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

tôi muốn chuyển đổi hình ảnh một lần trong quá trình khởi tạo và giữ một danh sách các nguồn hình ảnh. Tôi cũng giả định tôi sẽ cần một tài sản phụ thuộc để ràng buộc sự kiểm soát, nhưng tôi không chắc chắn làm thế nào để thiết lập khả năng với danh sách này của nguồn hình ảnh:


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

Trả lời

31

Mặc dù một nguồn tài nguyên hình ảnh trong một dự án WPF tạo ra một thuộc tính System.Drawing.Bitmap trong Resources.Designer.cs, bạn có thể trực tiếp tạo ra một BitmapImage từ tài nguyên đó. Bạn chỉ cần đặt Build Action của tệp hình ảnh thành Resource (thay vì mặc định là None).

Nếu bạn có tệp Red.jpg trong thư mục Resources của Dự án Visual Studio, việc tạo một BitmapImage sẽ giống như được hiển thị bên dưới. Nó sử dụng một WPF Pack Uri.

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

Nếu bạn có một kiểm soát Image tuyên bố ở đâu đó trong XAML như thế này:

<Image x:Name="image"/> 

bạn chỉ có thể thiết lập các Source tài sản của ảnh để BitmapImage của bạn trong mã đằng sau:

image.Source = bitmap; 

Trong trường hợp bạn muốn đặt Source tài sản bằng cách ràng buộc bạn có thể tạo ra một tài sản string trả về URI hình ảnh. Chuỗi này sẽ tự động được chuyển đổi thành một số BitmapImage bằng cách cài sẵn TypeConverter trong 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); } 
    } 
} 

Trong XAML bạn sẽ liên kết với tài sản đó như thế này:

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

Tất nhiên bạn cũng có thể kê khai tài sản là loại 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); } 
} 

và liên kết theo cùng một cách:

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

Bây giờ bạn có thể trước khi tải hình ảnh của bạn và đặt chúng vào bất động sản khi cần thiết:

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: Sau khi tất cả, hình ảnh của bạn không cần phải có nguồn lực trong dự án Visual Studio. Bạn chỉ có thể thêm một thư mục dự án, đặt các tập tin hình ảnh vào thư mục đó và đặt Build Action thành Resource. Ví dụ: nếu bạn gọi cho thư mục Images, URI sẽ là pack://application:,,,/Images/Red.jpg.

+0

Clemens Bạn đá! Đây là một phản ứng tuyệt vời, toàn diện, dễ hiểu. Tôi bị cám dỗ để sử dụng tùy chọn ràng buộc, nhưng trong trường hợp của tôi, tùy chọn đầu tiên của việc thiết lập nguồn trong mã-đằng sau chỉ là quá thanh lịch. Vấn đề duy nhất là tôi không thể làm cho nó hoạt động với các tệp png. Tôi đã hy vọng cho một nền tảng trong suốt. Nó có nên hoạt động với các tệp png không? Tôi chỉ làm điều gì đó sai, hoặc họ không được hỗ trợ? – dtaylor

+0

Điều này sẽ hoạt động tốt với các tệp PNG. Có lẽ bạn không nên thêm chúng làm tài nguyên cho dự án của bạn (xem bản chỉnh sửa của tôi). Chỉ cần tạo các tệp bằng công cụ hình ảnh yêu thích của bạn và thêm chúng vào một thư mục trong dự án của bạn. Xem [tại đây] (http://meta.stackexchange.com/a/5235) về việc chấp nhận. – Clemens

+0

Clemens, Một lần nữa bạn đã cung cấp một câu trả lời rõ ràng và súc tích! Tệp PNG hoạt động tốt khi tôi chỉ đơn giản là đặt nó vào một thư mục và biến nó thành một tài nguyên thay vì thêm nó như là một properties.resource trong Trình thiết kế tài nguyên. Cảm ơn rất nhiều. – dtaylor

Các vấn đề liên quan