2009-05-14 9 views
8

relacionados con mi pregunta anterior: Binding ComboBox.SelectedItem in SilverlightEncuadernación ComboBox.selectedItem en Silverlight (más)

Tengo un cuadro combinado con destino así:

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

Tanto el CurrentVideo y el cambio de propiedad CurrentCommentary regularidad. Después de algunas veces, aparece este error:

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) 

Esto me parece un error de ComboBox. Puedo verificar que CurrentVideo cambie antes de CurrentCommentary, por lo que el elemento seleccionado siempre debe ser un elemento que esté en la lista.

Relacionado, realmente no quiero el Modo = TwoWay, porque cuando se cambia ItemsSource, SelectedItem es temporalmente nulo, lo que se retrotrae en mi modelo, lo que en realidad no quiero. Pero el enlace no funciona en absoluto (lo que parece ser otro error).

+0

¿Está revisando para asegurarse de que CurrentCommentary todavía está en la lista CurrentVideo.Commentaries, porque si no lo está, obtendrá este error. –

+0

Inyecté un convertidor en ambas propiedades enlazadas para inspeccionar si el elemento seleccionado está o no en el ítem fuente. El problema parece ser: ItemsSource changes. Ese cambio hace que SelectedItem se vuelva nulo. SelectedCommentary cambia a nulo porque es un enlace bidireccional. SelectedCommentary se establece en el valor correcto por la aplicación, este valor es definitivamente dentro de ItemsSource. Ocurre un error Si el modo de enlace no es TwoWay, no hay ningún error, pero nunca se selecciona el elemento adecuado. –

Respuesta

0

Combobox es un control SL con errores bastante :-(

En mi caso me di por vencido con la unión del elemento seleccionado declarativa y utilizar el enfoque de codificación desagradable ... feo, pero funciona:.

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

HTH Braulio

+0

Publicación interesante, pero esto no parece realmente relevante para mi problema. Sin embargo, sí aprendí sobre DisplayMemberPath. Anteriormente, establecía un nuevo DataTemplate solo para mostrar una propiedad del elemento. –

0

que estaba recibiendo el mismo problema hace un tiempo y de lo que puedo decir que es un error en el cuadro combinado cuando el ItemSource se cambia tiene un problema con el diseño y SC rueda mal

Existe un problema llamando a ComboBox.UpdateLayout entre la configuración de ItemSource y SelectedItem.

He escrito sobre el problema hace un tiempo en Gotcha when databinding a ComboBox in Silverlight.

todavía tengo que verificar si el problema todavía existe en el Silverlight 3 Beta

+0

El uso de UpdateLayout es un buen enfoque, pero lo probé y todavía terminé con el mismo error. Lo obtengo al configurar SelectedItem en código o mediante enlace. –

+0

En el ejemplo de su blog está vinculando a una propiedad donde el getter está creando dinámicamente un nuevo OC en get. Esto cambiará el puntero utilizado por el enlace ItemsSource cada vez que se evalúa. Un enfoque más estable sería declarar un OC y agregarle elementos. Además, al construir dinámicamente un OC , no tiene sentido usar incluso un OC ; también podría utilizar una Lista . – markti

+0

De acuerdo, al final me moví a un modelo como ese, sin embargo, sigue siendo un error a tener en cuenta cuando se cambian las fuentes de los elementos. –

1

Gracias por las sugerencias anteriores. En mi situación, puedo ir a la "opción nuclear", que es: cada vez que el elemento seleccionado necesita cambiar, destruyo completamente el ComboBox, hago uno nuevo y establezco su SelectedItem de manera apropiada.

Ridículo, pero funciona.

13

Esto es un error en el control ComboBox que tiene que ver con el puntero cambiante del enlace de ItemsSource. La solución que he encontrado es:

1) Siempre vincule el ItemsSource a una colección observable y nunca restablezca el puntero del OC.

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

malo:

MyList = new ObservableCollection(); 

bueno:

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

2) Establecer myItem = null, antes de borrar Mi lista

En su caso va a cambiar la referencia de la lista cada vez que cambie CurrentView. Por lo tanto, si SelectedItem no es nulo, hay un breve momento en el tiempo donde ItemsSource se restablece, las partes internas de ComboBox intentan localizar el objeto SelectedItem en la nueva ItemsSource pero el objeto antiguo no está allí.

+0

Gracias por esta sugerencia @markti. Tuve el mismo error en mi aplicación Windows 8.1 Store y me estaba llevando a terapia. El hecho interesante es que acabo de utilizar el mismo enfoque que funciona perfectamente bien en una vista diferente, enfoque donde ItemsSource de mi ComboBox está vinculado a una Lista <> y no a una ObservableCollection. Será mejor que vuelva y lo cambie allí también. – Eddie