2009-12-15 19 views
5

को मैं इस सवाल को देखा है कई बार पूछा और अधिक से अधिक मेरे कोड पर चले गए हैं। लेकिन जब मैं किसी ऑब्जेक्ट के साथ अपने SelectedItem -बाउंड संपत्ति को असाइन करता हूं, तो यह डिस्प्ले के चयनित आइटम को अपडेट नहीं करता है। ऐसा लगता है कि ListBox सोचता है कि मेरे द्वारा निर्दिष्ट ऑब्जेक्ट अपने आइटम का सदस्य नहीं है।ListBox TwoWay बाँध SelectedItem

public class MainViewModel : ViewModelBase 
{ 
    //... 
    public SortedObservableCollection<TubeViewModel> Items { get; private set; } 
    public TubeViewModel SelectedTube { //get, set, propertychanged, etc. } 
} 

<ListBox x:Name="TubeList" 
     Margin="10" 
     ItemsSource="{Binding Items}" 
     ItemTemplate="{StaticResource TubeTemplate}" 
     SelectedItem="{Binding SelectedTube, Mode=TwoWay}" 
     SelectionMode="Single" 
     VirtualizingStackPanel.IsVirtualizing="False"> 
</ListBox> 

यहाँ स्थानों पर जहां मैं SelectedTube सेट करने का प्रयास में से एक से impl है - निश्चित रूप से मुख्य थ्रेड पर होता है।

var match = 
    from t in Items 
    where t.Model.DataFileName == filename 
    select t; 
if (match.Any()) 
    SelectedTube = match.First(); 

मैं देख रहा था कि SelectedTube जब तक मैं मैन्युअल रूप से उस पर क्लिक किया है, लेकिन एक तरह से इसे नजरअंदाज प्रकाश डाला कभी नहीं किया गया था। लेकिन तब मैं चयनित आइटम ScrollIntoViewCentered करना चाहता था, इसलिए मैं SelectedItem परिवर्तन के लिए देखने के लिए मेरे विचार में एक DependencyProperty गयी। हैंडलर शुरू में तो की तरह दिखाई देता:

private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) 
{ 
    if (TubeList.SelectedItem == null) 
     return; 

    TubeList.ScrollIntoViewCentered(TubeList.SelectedItem); 
} 

लेकिन अगर मैं अपने बंधन के माध्यम से SelectedItem सेट काम नहीं किया। निर्णय लेने से मैं केवल यह स्क्रॉल करने के लिए अगर यह स्क्रीन पर नहीं था के बाद, मैं यह करने के लिए कोड बदल दिया है:

private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) 
{ 
    if (TubeList.SelectedItem == null) 
     return; 

    var container = TubeList.ItemContainerGenerator.ContainerFromItem(TubeList.SelectedItem) as FrameworkElement; 

    if(!container.IsVisible) 
     TubeList.ScrollIntoViewCentered(TubeList.SelectedItem); 
} 

तो SelectedItem बाहर से सेट किया गया है, कंटेनर रिक्त है। हर बार। मैं भी अशक्त के लिए जाँच करने के लिए और फिर ItemsSource से अधिक पुनरावृति एक फ़ाइल नाम मैच के लिए देख रहा है, तो अद्यतन SelectedItem यकीन SelectedItem निश्चित रूप से लिस्टबॉक्स में एक वस्तु था बनाने के लिए कोड जोड़ा। कोई भाग्य नहीं।

यह एक दृश्यता बात, अगर आइटम स्क्रीन पर है नहीं है, यह अभी भी उजागर नहीं करता है। क्या मुझे कुछ प्रकार के समानता समारोह को लागू करने की आवश्यकता है? मैंने इस पर संभव सोचने से अधिक समय बर्बाद कर दिया है।

धन्यवाद।

+0

मैं इसे आपके कोड के बारे में जो कुछ भी देखता हूं उसके साथ पुन: उत्पन्न करने में सक्षम नहीं था। मैंने TubeViewModel के लिए एक डमी क्लास बनाया और आपके सभी पोस्ट कोड का उपयोग किया और यह अपेक्षित के रूप में काम किया। कहीं और कुछ चलना चाहिए। –

+0

बहुत बहुत धन्यवाद, बेन और केंट। मैं थोड़ी देर के लिए छुट्टी पर बंद हूँ, इसे इंतजार करना होगा। – Thomas

उत्तर

5

हो सकता है कि यह भी सच है कि ItemContainerGenerators एक अलग थ्रेड में उत्पन्न कर रहे हैं से संबंधित है ... (at least in the TreeView)

बुला UpdateLayout() इससे पहले कि आप ItemContainerGenerators संपत्ति पूछने की कोशिश करें।

+0

मुझे नहीं पता कि यह क्यों जरूरी है, लेकिन मुझे खुशी है कि यह है। अनेक अनेक धन्यवाद। – Thomas

3

कुछ भी नहीं स्पष्ट रूप से गलत रूप में मुझ पर बाहर कूदता है, लेकिन आप एक बहुत अधिक भुला दिया है। मैं केवल सुझाव दे सकता हूं कि जब तक आप या तो समस्या नहीं पाते हैं, या एक पूर्ण गैर-कार्य उदाहरण है जिसे आप पोस्ट कर सकते हैं।

1

आप वस्तु आप स्थापित करने के लिए कोशिश कर रहे हैं की hashCode के खिलाफ ItemSource में प्रत्येक वस्तु के hashCode जाँच करने की कोशिश की है? लिंक क्वेरी कुछ अलग लौटाएगी।

चयनित सामग्री को आइटम [0] पर सेट करने का प्रयास करने के परीक्षण के रूप में।