2009-08-13 27 views
22

मैं, और ViewModel IsSelected को ListViewItem.IsSelected जुड़ कर एक चयन पैटर्न this post में वर्णित IsSelected मूल्य स्टोर करने के लिए एक ViewModel का उपयोग कर के समान लागू कर दिया है:VirtualizingStackPanel + MVVM + एकाधिक चयन

<ListView.ItemContainerStyle> 
    <Style TargetType="{x:Type ListViewItem}"> 
     <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/> 
    </Style> 
</ListView.ItemContainerStyle> 

यह काम करता है सामान्य रूप से, लेकिन मुझे एक गंभीर समस्या का सामना करना पड़ता है। सूची दृश्य में पैनल के रूप में VirtualizingStackPanel का उपयोग करके, केवल ListViewItem दिखाई दे रहे हैं। यदि मैं सभी आइटमों का चयन करने के लिए "Ctrl + A" का उपयोग करता हूं, या पहले आइटम पर शॉर्टकट संयोजन जैसे "Shift + Ctrl + End" का उपयोग करके, सभी आइटम चुने जाते हैं, लेकिन गैर दृश्यमान वस्तुओं के लिए, ViewModel को इसके चयन नहीं किया जाता है सच करने के लिए सेट करें। यह तार्किक है, क्योंकि यदि ListViewItem नहीं बनाए गए हैं, तो बाध्यकारी काम नहीं कर सकता है।

किसी को भी एक ही समस्या का अनुभव हुआ, और एक समाधान मिला (VirtualizingStackPanel का उपयोग न करने के अलावा)?

+0

इस समस्या के लिए यह पूर्ण समाधान का प्रयास करेंhttp://stackoverflow.com/a/29545790 – nvkokorin

उत्तर

28

मुझे एमवीवीएम पैटर्न में चयन को संभालने का एक और तरीका मिला, जिसने मेरी समस्या हल की। व्यूमोडेल में चयन को बनाए रखने के बजाय, चयन सूची दृश्य/सूची बॉक्स से पुनर्प्राप्त किया गया है, और कमांड के पैरामीटर के रूप में पारित किया गया है। सभी XAML में किया:

मेरी ViewModel में
<ListView 
    x:Name="_items" 
    ItemsSource="{Binding Items}" ... /> 

<Button 
    Content="Remove Selected" 
    Command="{Binding RemoveSelectedItemsCommand}" 
    CommandParameter="{Binding ElementName=_items, Path=SelectedItems}"/> 

:

private void RemoveSelection(object parameter) 
{ 
    IList selection = (IList)parameter; 
    ... 
} 
+5

मुझे यह दृष्टिकोण पसंद है, लेकिन आप इस तरह से व्यूमोडेल से प्रोग्रामेटिक रूप से आइटम का चयन नहीं कर सकते हैं। –

+1

यदि सूचीदृश्य और बटन अलग-अलग उपयोगकर्ता नियंत्रण क्षेत्र में हैं तो यह काम नहीं करेगा। –

1
VirtualizingStackPanel का उपयोग नहीं कर से

अलावा, केवल एक चीज मैं के बारे में सोच सकते हैं उन के लिए कीबोर्ड शॉर्टकट को पकड़ने और ताकि उनके IsSelected संपत्ति True (जैसे, SelectAll(), SelectFromCurrentToEnd() पर सेट है अपने ViewModel मदों की एक निश्चित सीमा को संशोधित करने के लिए तरीके है)। इस तरह के मामलों के चयन को नियंत्रित करने के लिए मूल रूप से BindingListViewItem पर बाईपास करना।

+2

कीबोर्ड या माउस के साथ होने वाले सभी अलग-अलग तरीकों को न भूलें! Ctrl + A, Shift + End, Shift + Home, और आप माउस के साथ एक मनमानी रेंज को Shift-Click कर सकते हैं; ये सभी चीजें एक ही समस्या का कारण बन सकती हैं। – Qwertie

3

मेरे मामले में, मैं ListBox से एक ListBoxEx वर्ग पाने, और चयन परिवर्तन करने के लिए प्रतिक्रिया करने के लिए कोड जोड़कर इस सुलझाने समाप्त हो गया, को लागू करने आइटम दृश्य मॉडल पर चयन राज्य: :

private readonly List<IListItemViewModelBase> selectedItems = new List<IListItemViewModelBase>(); 

protected override void OnSelectionChanged(SelectionChangedEventArgs e) 
{ 
    base.OnSelectionChanged(e); 

    bool isVirtualizing = VirtualizingStackPanel.GetIsVirtualizing(this); 
    bool isMultiSelect = (SelectionMode != SelectionMode.Single); 

    if (isVirtualizing && isMultiSelect) 
    { 
     var newSelectedItems = SelectedItems.Cast<IListItemViewModelBase>(); 

     foreach (var deselectedItem in this.selectedItems.Except(newSelectedItems)) 
     { 
      deselectedItem.IsSelected = false; 
     } 

     this.selectedItems.Clear(); 
     this.selectedItems.AddRange(newSelectedItems); 

     foreach (var newlySelectedItem in this.selectedItems) 
     { 
      newlySelectedItem.IsSelected = true; 
     } 
    } 
} 
संबंधित मुद्दे