2011-07-12 2 views
2

わかりました。わかりやすいプログラムには、顧客リストがあります。これらの顧客はリストボックスにすべてリストされているため、フォーム上にすべての情報がクリックされたときに表示されます。これはデータバインディングを介して動作し、ページ上のすべてのコントロールはリストボックスのselectedItemにバインドされます。WPFリストボックスコマンド

私が今したいのは、ユーザーが選択を変更しようとしたときに保存したいかどうかを尋ねるメッセージダイアログがあります。彼らがしなければ私はコレクションの元のアイテムに戻したいと思います。彼らがキャンセルを押すと、前回選択したアイテムにフォーカスを当てるように選択します。私はMVVMのやり方でこれを達成する最良の方法は何だろうと思っていますか?

現在、私は顧客のためのモデルを持っており、VMは、リストボックスがバインドされている顧客のコレクションを埋めます。それで、リストボックスのselectedIndexを操作できることを含む、VM上の選択変更イベントを処理する方法はありますか? ここに私のコードがありますので、私が何をしているのかを見ることができます。あなたが変更されたイベントをキャッチすることができます

   if (value != _selectedAccount) 
       { 
        MessageBoxResult mbr = MessageBox.Show("Do you want to save your work?", "Save", MessageBoxButton.YesNoCancel); 
        if (mbr == MessageBoxResult.Yes) 
        { 
         //Code to update corporate 
         Update_Corporate(); 
         _preSelectedAccount = value; 
         _selectedAccount = value; 
        } 
        if (mbr == MessageBoxResult.No) 
        { 
         //Do Stuff 

        } 
        if (mbr == MessageBoxResult.Cancel) 
        { 

         SelectedAccount = _preSelectedAccount; 
         NotifyPropertyChanged("SelectedAccount"); 
        } 

       } 

答えて

1

XAML:

<ListBox ItemsSource="{Binding Customers}" SelectedItem="{Binding SelectedCustomer}" DisplayMemberPath="CustomerName"/> 

のViewModel:

private Customer selectedCustomer; 
public Customer SelectedCustomer 
{ 
    get 
    { 
    return selectedCustomer; 
    } 
    set 
    { 
    if (value != selectedCustomer) 
    { 
     var originalValue = selectedCustomer; 
     selectedCustomer = value; 
     dlgConfirm dlg = new dlgConfirm(); 
     var result = dlg.ShowDialog(); 
     if (!result.HasValue && result.Value) 
     { 
     Application.Current.Dispatcher.BeginInvoke(
      new Action(() => 
      { 
       selectedCustomerr = originalValue; 
       OnPropertyChanged("SelectedCustomer"); 
      }), 
      System.Windows.Threading.DispatcherPriority.ContextIdle, 
      null 
     ); 
     } 
     else 
     OnPropertyChanged("SelectedCustomer"); 
    } 
    } 
} 

が取ら/ hereからのさらなる情報を。

+0

私のソリューションはこれに非常によく似ていますが、私には1つの問題があります。ユーザーがキャンセルを押すと、その場所をそのまま残しておくことができますが、ビューではユーザーがクリックしたアイテムが強調表示されますが、フォームの残りのアカウント情報はキャンセルのように残ります。 –

+0

ええと、ディスパッチャを使用して、選択したインデックスが更新された後に元に戻って行く必要があるようです。上記を反映するように更新された上記のコード、more info [here](http://blog.alner.net/archive/2010/04/25/cancelling-selection-change-in-a-bound-wpf-combo-box.aspx )。 –

+0

リンクのおかげで、私は記事のコメントを読んで、CollectionViewSourceを使って下に投稿された別のアプローチを使用しました。ちょうど、上記のメソッドがうまく動作していると思うバインディングで、IsAsyncプロパティをtrueに設定した場合は、そのことを言いたいと思います。 –

2

最良の方法は、セットにあなたは何をする必要があるか行うことができ、あなたのビューモデル内の別のプロパティにリストボックスののSelectedItemをバインドすることです:

private Customer selectedCustomer; 
public Customer SelectedCustomer 
{ 
    get { return selectedCustomer; } 
    set 
    { 
     if (selectedCustomer== value) return; 
     selectedCustomer = value; 
     RaisePropertyChanged("SelectedCustomer"); 
     // Do your stuff here 
    } 
} 

これは、MVVMライト(RaisePropertyChanged)を使用した例です。