2009-05-14 8 views
8

Podobne do mojego poprzedniego pytania: Binding ComboBox.SelectedItem in SilverlightOprawa ComboBox.SelectedItem w Silverlight (więcej)

Mam ComboBox związany tak:

<ComboBox x:Name="PART_CommentaryList" 
    HorizontalAlignment="Left" 
    Margin="3" 
    ItemsSource="{Binding Path=CurrentVideo.Commentaries}" 
    SelectedItem="{Binding Path=CurrentCommentary, Mode=TwoWay}"> 

Zarówno CurrentVideo i CurrentCommentary zmiana nieruchomość regularnie. Po kilku chwilach pojawia się ten błąd:

Category: ManagedRuntimeError  
Message: System.ArgumentException: Value does not fall within the expected 
    range. 
    at MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, 
     CValue[] cvData) 
    at MS.Internal.XcpImports.MethodPack(IntPtr objectPtr, String methodName, 
     Object[] rawData) 
    at MS.Internal.XcpImports.UIElement_TransformToVisual(UIElement element, 
     UIElement visual) 
    at System.Windows.UIElement.TransformToVisual(UIElement visual) 
    at System.Windows.Controls.Primitives.Selector.IsOnCurrentPage(
     Int32 index, Rect& itemsHostRect, Rect& listBoxItemRect) 
    at System.Windows.Controls.Primitives.Selector.ScrollIntoView(
     Int32 index) 
    at System.Windows.Controls.Primitives.Selector.SetFocusedItem(
     Int32 index, Boolean scrollIntoView) 
    at System.Windows.Controls.ComboBox.PrepareContainerForItemOverride(
     DependencyObject element, Object item) 
    at System.Windows.Controls.ItemsControl.UpdateContainerForItem(
     Int32 index) 
    at System.Windows.Controls.ItemsControl.RecreateVisualChildren() 
    at System.Windows.Controls.ItemsControl.RecreateVisualChildren(
     IntPtr unmanagedObj) 

Wydaje mi się, że to błąd ComboBox. Mogę zweryfikować, że CurrentVideo zmienia się przed bieżącąComentarzem, więc wybrany element powinien zawsze być elementem, który znajduje się na liście.

Powiązane, Naprawdę nie chcę trybu = TwoWay, ponieważ gdy ItemsSource jest zmieniony, SelectedItem jest chwilowo pusty, co zostaje cofnięte w moim modelu, czego tak naprawdę nie chcę. Ale powiązanie w ogóle nie działa (co wydaje się być kolejnym błędem).

+0

Czy sprawdzasz, aby upewnić się, że CurrentCommentary nadal znajduje się na liście CurrentVideo.Commentaries, ponieważ w przeciwnym razie pojawi się ten błąd. –

+0

Wprowadziłem konwerter do obu właściwości związanych, aby sprawdzić, czy wybrany element rzeczywiście znajduje się w źródle materiałów. Wydaje się, że problem: Zmiany ItemsSource. Ta zmiana powoduje, że SelectedItem ma wartość NULL. SelectedCommentary zmienia się na wartość null, ponieważ jest to wiązanie dwukierunkowe. SelectedCommentary jest ustawiona na właściwą wartość przez aplikację, ta wartość jest zdecydowanie w ItemsSource. Błąd się dzieje. Jeśli tryb bindowania nie jest TwoWay, nie ma błędu, ale wtedy właściwy element nigdy nie jest wybierany. –

Odpowiedz

0

ComboBox jest dość SL kontrola buggy :-(

W moim przypadku zrezygnowałem z wiążący wybrany declarativa pozycję i paskudny podejście kodowania ... brzydki, ale działa.

http://blogs.msdn.com/mikehillberg/archive/2009/03/26/implementing-selectedvalue-with-the-silverlight-combobox.aspx

HTH Braulio

+0

Interesujący post, ale nie wydaje mi się to istotne dla mojego problemu. Dowiedziałem się jednak o DisplayMemberPath. Poprzednio ustawiałem nowy DataTemplate tylko po to, aby wyświetlić właściwość elementu. –

0

i był już ten sam problem jakiś czas temu i od tego, co mogę powiedzieć to to błąd w ComboBox gdy ItemSource zostanie zmieniona ma problem z układem i sc toczy się źle.

Istnieje praca wokół wywołania ComboBox.UpdateLayout między ustawieniem ItemSource i SelectedItem.

Niedawno napisałem o problemie na blogu pod adresem Gotcha when databinding a ComboBox in Silverlight.

jeszcze mam sprawdzić, czy problem nadal istnieje w Silverlight 3 Beta

+0

Korzystanie z UpdateLayout jest dobrym podejściem, ale zrobiłem to i wciąż kończyłem z tym samym błędem. Otrzymuję go podczas ustawiania SelectedItem w kodzie lub przez powiązanie. –

+0

W przykładowym blogu wiążemy właściwość, w której pobierający dynamicznie tworzy nowy kod OC przy pobieraniu. Spowoduje to zmianę wskaźnika używanego przez powiązanie ItemsSource za każdym razem, gdy jest oceniany. Bardziej stabilnym podejściem byłoby zadeklarowanie OC i dodanie do niego elementów. Ponadto, dynamicznie konstruując OC , nie ma sensu nawet używać OC , możesz równie dobrze użyć Listy . – markti

+0

Zgadzam się, w końcu przeszedłem do modelu takiego jak ten, jednak nadal jest to błąd, którego należy dopilnować przy zmianie źródeł przedmiotów. –

1

Dzięki za sugestie powyżej. W mojej sytuacji jestem w stanie wybrać "opcję jądrową", która - gdy tylko wybrany element wymaga zmiany, całkowicie zniszczę ComboBox, utworzę nowy i odpowiednio ustawię SelectedItem.

Śmieszne, ale działa.

13

To błąd w kontrolce ComboBox, który ma związek ze zmieniającym się wskaźnikiem powiązania ItemsSource. Rozwiązanie, które znalazłem, to:

1) Zawsze wiążę ItemSource z obserwowalną kolekcją i nigdy nie resetuję wskaźnika OC.

<ComboBox ItemsSource="{Binding MyList}" SelectedItem="{Binding MyItem}" /> 

Źle:

MyList = new ObservableCollection(); 

Dobre: ​​

MyList.Clear(); 
MyList.AddRange(...); 

2) Ustaw MyItem = null, przed Clearing mylist

w Twoim przypadku zmieniasz odniesienie do listy za każdym razem, gdy zmieniasz CurrentView. Dlatego jeśli SelectedItem nie ma wartości null, istnieje krótki moment w czasie, gdy ItemsSource jest resetowany, elementy wewnętrzne ComboBox próbują zlokalizować obiekt SelectedItem w nowym ItemSource, ale nie ma tam starego obiektu.

+0

Dzięki za tę sugestię @markti. Miałem ten sam błąd w mojej aplikacji Windows 8.1 Store i to doprowadzało mnie do terapii. Ciekawe jest to, że użyłem tego samego podejścia, które działa zupełnie dobrze w innym widoku, podejściu, w którym pozycja ItemsSource w ComboBox jest powiązana z List <>, a nie z ObservableCollection. Lepiej wrócę i tam też zmienię. – Eddie