2011-02-12 80 views
4

我目前正在學習如何使用MVVM模式編寫WPF應用程序。我正在編寫一個小的聯繫人管理器應用程序,所以我的應用程序顯示一個綁定到我的視圖模型的Listbox,以及一組綁定到ListBox.SelectedItem的字段。其中一個領域是聯繫人的照片。WPF&MVVM:更新圖像字段而不會破壞模式

我想使用OpenFileDialog更改編輯部分中的照片,所以Listbox項目會更新,因爲它是所有其他字段。

我首先嚐試更新Image控件的源屬性,但是這樣做,我失去了綁定...然後,我在Button_Click上編寫了一個處理程序來更新Contact.Photo屬性(其類型爲byte [] ),它的工作原理。但不是從「更新控制」綁定到視圖模型,而是綁定從虛擬機到控件,就好像數據來自數據庫。

(在代碼中,LoadPhoto返回一個byte [])我不知道,如果它不破MVVM模式

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    OpenFileDialog OpenFileDialog = new OpenFileDialog(); 
    if (OpenFileDialog.ShowDialog() == true) 
    { 
     (listbox.SelectedItem as ContactManager.ViewModel.Contact).Photo = 
       LoadPhoto(OpenFileDialog.FileName); 
    } 
} 

...我不知道什麼可以在視圖中進行...這是更新聯繫人對象的正確方法嗎?有沒有人有更好的解決這個問題?

回答

2

查看將您的按鈕綁定到Command Binding而不是Click事件。
您可以使用Google查找DelegateCommand的實現。
接下來,您可以從ViewModel中公開一個ImageSource,您可以從您的XAML綁定到您的圖像。

我已經包含了一些代碼片段以幫助您入門。

一旦你過去的基礎看看MVVM框架,如Cinch,你會找到一個方法使用Services Interfaces IOpenFileService.cs不違反MVVM模式來處理打開文件對話框。

這裏是XAML:

<Button Content="Update Photo" Command="{Binding UpdatePictureCommand}"/> 

    <Image Source="{Binding EmployeePicture}" 
        VerticalAlignment="Center" HorizontalAlignment="Center" 
        Stretch="Fill" /> 

這裏是視圖模型:

public MainViewModel() 
    { 
    UpdatePictureCommand = new DelegateCommand<object>(OnUpdatePictureCommand, CanUpdatePictureCommand); 
    } 

    public ICommand UpdatePictureCommand { get; private set; } 
    private void OnUpdatePictureCommand(object obj) 
    { 
    OpenFileDialog OpenFileDialog = new OpenFileDialog(); 
    if (OpenFileDialog.ShowDialog() == true) 
    { 
    //(listbox.SelectedItem as ContactManager.ViewModel.Contact).Photo = 
    // LoadPhoto(OpenFileDialog.FileName); 
    Stream reader = File.OpenRead(OpenFileDialog.FileName); 
    System.Drawing.Image photo = System.Drawing.Image.FromStream((Stream)reader); 

    MemoryStream finalStream = new MemoryStream(); 
    photo.Save(finalStream, ImageFormat.Png); 

    // translate to image source 
    PngBitmapDecoder decoder = new PngBitmapDecoder(finalStream, BitmapCreateOptions.PreservePixelFormat, 
             BitmapCacheOption.Default); 
    EmployeePicture = decoder.Frames[0];; 
    } 

    private bool CanMoveFirstCommand(object obj) 
    { 
    return true; 
    } 

    private ImageSource _employeePicture; 
    public ImageSource EmployeePicture 
    { 
    get 
    { 
     return _employeePicture; 
    } 
    set 
    { 
     _employeePicture = value; 
     OnPropertyChanged("EmployeePicture"); 
    } 
    } 
+0

我已經嘗試過使用命令的命令參數(更新對象),以及看起來像我的代碼你的。但是我對這種方式懷疑同樣的事情:VM中的OpenFileDialog是不是打破了這種模式?我會試着讓Cinch看看如何解決這個問題。 – Seb 2011-02-12 18:40:48