2013-06-25 5 views
5

を結合私は結合(これは、結合がやや異例である理由である、DataTemplateで定義されている)を介して動的に取り込むListBoxを持っている:リストボックス「IsSelected」部分的にしか作業

<ListBox SelectionMode="Extended" ItemsSource="{Binding DataContext.ResultList, RelativeSource={RelativeSource AncestorType=Window}}"> 
    <ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="IsSelected" Value="{Binding IsSelected}"/> 
    </Style> 
    </ListBox.ItemContainerStyle> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <Label Content="{Binding Object}"/> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

ListBoxItem " s IsSelectedプロパティは、カスタムオブジェクトのIsSelectedプロパティにバインドされています。

個別にListBoxItemを選択すると、バインドが正しく機能します。カスタムオブジェクトのIsSelectedプロパティが、自分のViewModelで更新されます。ただし、Ctrl + AコマンドでListBoxItemをすべて選択すると、現在表示されているListBoxItem(現在スクロールしているビューポートにあるもの)のみがViewModelバインディングを更新します。フロントエンドでは、ListBoxItemがすべて選択されているように見え、ListBoxListBox.SelectedItems.Countプロパティはすべての項目が選択されていることを示します。

さらに、ListBoxItemをCtrl + Aで選択した後にListBoxをスクロールすると、各ListBoxItemがスクロールされて表示されると、バインディングが正常に更新されます。

なぜこのバインディングは部分的にしか機能していないようですか?多数のListBoxItemsを同時に選択できるときに、IsSelectedプロパティのバインドを処理するより良い方法はありますか?

編集: この動作は、Ctrlキー+コマンドで独占的に発生しません - シフト+クリックを使用して、すべての項目を選択するとき、私は同じ結果を得ます。

+1

私はUIに依存せず、 'KeyBinding'を入れてViewModelでやるか、いくつかのコードを後ろに置き、選択ロジックをVMに委譲します。または、そのキーの組み合わせに反応する行動または何かを入れます。 –

+0

@HighCore - Select Allコマンドでのみ問題は発生しません。シフト+クリックを使用してすべてのアイテムを選択すると同じ問題が発生します。 –

+1

私はこの同じ種類の問題に遭遇しました。私はあきらめて、[SelectedItems](http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.selecteditems.aspx)へのバインディングをクリックハンドラの引数として使用しました。ボタンを押して、それを1日と呼びました(コマンドのCommandParameterとして使用することもできます)。リストが長くなったときに仮想化を無効にすることは、パフォーマンスにはあまり価値がないのです。 –

答えて

5

私はあなたが見ている行動は、あなたが例えばのためにあなたのListBoxように設定した場合ListBox

ItemsSourceに結合するときにデフォルトでTrueあるVirtualizingStackPanel.IsVirtualizingに起因していると思う:

<ListBox VirtualizingStackPanel.IsVirtualizing="False" SelectionMode="Extended" ItemsSource="{Binding DataContext.ResultList, RelativeSource={RelativeSource AncestorType=Window}}"> 

<ListBox ...> 
    ... 
    <ListBox.ItemsPanel> 
    <ItemsPanelTemplate> 
     <StackPanel /> 
    </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
</ListBox> 

次に、バインドされたアイテムのすべてがIsSelectedは、Ctrlキー+ Aとに応じて更新または... +なども、必要なScrollBar.Heightを計算するようなもののために対応するために、正しい値を報告する仮想化コレクションのCountとして

プロパティをシフトします。ビューポートの外にあるアイテムはレンダリングされないので、実際に使用されるまでバインドは有効になりません。

+0

それはそれをしました!ありがとう、偉大なキャッチ! –

+0

それは働いた。しかし、この仮想化とは何で、なぜそれが問題を引き起こしたのですか? –

+0

"標準レイアウトシステムでは、アイテムコンテナを作成し、リストコントロールに関連付けられた各アイテムのレイアウトを計算します。「仮想化」という用語は、UIエレメントのサブセットを、 VirtualizingStackPanelは、目に見えるアイテムの数を計算し、ItemsControl(ListBoxやListViewなど)のItemContainerGeneratorで動作してUIを作成するために使用されます目に見えるアイテムの要素のみ。 –

関連する問題