15

ListView.SelectedItems自明ではない量のコードでデータバインディング機能を追加することについて議論している投稿がいくつかあります。私のシナリオでは、から設定する必要はありませんViewModel。アクションを実行するために選択したアイテムを取得するだけで、コマンドによってトリガーされるため、プッシュ更新も必要ありません。

おそらくコードビハインドで、(コード行に関して)簡単な解決策はありますか? 相互に参照する必要がない限り、分離コードで問題Viewありません。ViewModelこれはより一般的な質問だと思います:「VMがオンデマンドでビューからデータを取得するためのベストプラクティス」ですが、何も見つからないようです...

4

5 に答える 5

28

SelectedItemsコマンドが実行されたときにのみを取得するには、 を使用CommandParameterして渡しListView.SelectedItemsます。

<ListBox x:Name="listbox" ItemsSource="{Binding StringList}" SelectionMode="Multiple"/>
<Button Command="{Binding GetListItemsCommand}" CommandParameter="{Binding SelectedItems, ElementName=listbox}" Content="GetSelectedListBoxItems"/>
于 2012-06-12T23:35:24.250 に答える
4

「 View と ViewModel はお互いを知る必要がない」と考えるのは正しい条件ではないと思います。MVVM ビューでは、常に ViewModel について知っています。

ビューのコード ビハインドで ViewModel にアクセスし、いくつかのデータ (選択したアイテムなど) を入力する必要があるこのような状況にも遭遇しました。これは、ListView、DataGrid などのサードパーティ コントロールを使用しているときに必要になります。

VM プロパティを直接バインドできない場合は、ListViw.SelectionChanged イベントをリッスンし、そのイベントで ViewModels SelectedItems プロパティを更新します。

アップデート:

VM がビューからデータをプルできるようにするには、ビュー固有の機能を処理するビューでインターフェイスを公開できます。ビューモデルは、そのインターフェイスを介してビューを参照します。インターフェイスを使用しても、View と ViewModel は大部分が分離されたままになりますが、私は一般的にこれを好みません。

ViewModel への View の関連付けを提供する MVVM

View でイベントを処理し、VM を (選択したアイテムで) 更新し続けるアプローチを引き続き好むでしょう。この方法では、VM は操作を実行する前にデータをプルすることを心配する必要はありません。利用可能なデータを使用するだけで済みます。 (それは常に更新されるため)。

于 2012-06-10T06:03:44.533 に答える
3

私はあなたを保証することができます: SelectedItemsは実際に XAML CommandParameterとしてバインド可能です

多くの掘り下げとグーグル検索の後、私は最終的にこの一般的な問題に対する簡単な解決策を見つけました。

それを機能させるには、次のすべてのルールに従う必要があります。

  1. Ed Ball の提案に従って、XAML コマンドのデータバインディングでCommandParameterプロパティを BEFORE Commandプロパティに定義します。これは非常に時間のかかるバグです。

  2. ICommandCanExecuteおよびExecuteメソッドにオブジェクト型のパラメーターがあることを確認してください。このようにして、データバインド CommandParameter型がコマンド メソッドのパラメーター型と一致しない場合に発生するサイレントキャスト例外を防ぐことができます。

    private bool OnDeleteSelectedItemsCanExecute(object SelectedItems)  
    {
        // Your goes heres
    }
    
    private bool OnDeleteSelectedItemsExecute(object SelectedItems)  
    {
        // Your goes heres
    }
    

たとえば、リストビュー/リストボックスのSelectedItemsプロパティをICommandメソッドに送信するか、リストビュー/リストボックス自体に送信できます。いいですね。

SelectedItemsCanExecuteパラメータとして受け取る方法を理解するために私が費やした膨大な時間を誰かが費やすのを防ぐことを願っています。

于 2014-09-22T02:06:55.140 に答える
0

他の回答はどれも役に立たなかったので (いつものSelectedItemsように使用)、ユニバーサル Windows プラットフォーム (UWP) アプリのソリューションを次に示します。と を使用して動作します。CommandParameternullMicrosoft.Xaml.InteractivityMicrosoft.Xaml.Interactions.Core

ビューは次のとおりです。

<ListView x:Name="ItemsList">
    <Interactivity:Interaction.Behaviors>
         <Core:EventTriggerBehavior EventName="SelectionChanged">
             <Core:InvokeCommandAction Command="{x:Bind ViewModel.SelectedItemsChanged}" />
         </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
    <!-- content etc. -->
</ListView>

ViewModel は次のとおりです (RelayCommandは MVVM Light のクラスです)。

private List<YourType> _selectedItems = new List<YourType>();

private RelayCommand<SelectionChangedEventArgs> _selectedItemsChanged;
public RelayCommand<SelectionChangedEventArgs> SelectedItemsChanged
{
    get
    {
        if (_selectedItemsChanged == null)
            _selectedItemsChanged = new RelayCommand<SelectionChangedEventArgs>((selectionChangedArgs) =>
            {
                // add a guard here to immediatelly return if you are modifying the original collection from code

                foreach (var item in selectionChangedArgs.AddedItems)
                    _selectedItems.Add((YourType)item);

                foreach (var item in selectionChangedArgs.RemovedItems)
                    _selectedItems.Remove((YourType)item);
            });
        return _selectedItemsChanged;
    }
}

選択が完了した後 (ユーザーがボタンを押すなど) に元のコレクションからアイテムを削除しようとすると、リストからアイテムも削除されることに注意してください_selectedItems。これを foreach ループで実行すると、InvalidOperationException. これを回避するには、次のようにマークされた場所にガードを追加するだけです。

if (_deletingItems)
    return;

次に、たとえばアイテムを削除するメソッドで、次のようにします。

_deletingItems = true;
foreach (var item in _selectedItems)
    YourOriginalCollection.Remove(item);
_deletingItems = false;
于 2016-04-05T20:35:22.957 に答える