silverlight-2.0

silverlight 2.0 - Acceda al contexto de datos padre en el cuadro de lista en Silverlight



silverlight-2.0 (4)

He estado luchando con un problema similar. El mío consiste en un cuadro combinado que se muestra para cada elemento de lista. El DataContext de nivel superior está vinculado a mi modelo de vista (MVVM) y se ve así:

class ViewModel{ ObservableCollection<ComboboxListItemType> DataForTheComboBoxList; ObservableCollection<MyDataType> DataForTheListBox; ... }

Como el cuadro combinado está dentro de ItemTemplate (= DataTemplate) para el cuadro de lista, el DataContext para cada elemento de lista se establece en el elemento apropiado en DataForTheListBox, el cuadro combinado ya no puede ver el DataForTheComboBoxList que necesita del DataContext de nivel superior.

Mi (sucia, fea) solución implica establecer la lista completa de combobox en cada elemento de la lista, por lo que se vuelve visible para el DataContext en este elemento de la lista.

Primero, realiza una clase parcial para su tipo de datos listbox. (En general, esto vendrá de una referencia de servicio, por lo que no puede tocar el código generado directamente sin perderlo potencialmente). Esta clase parcial contiene una nueva propiedad que hace referencia al tipo de elemento de la lista desplegable:

public partial class MyDataType { private ObservableCollection<ComboboxListItemType> m_AllComboboxItems; public ObservableCollection<ComboboxListItemType> AllComboboxItems { get { return m_AllComboboxItems; } set { if (m_AllComboboxItems != value) { m_AllComboboxItems = value; RaisePropertyChanged("AllComboboxItems"); } } } }

A continuación, debe establecer esta propiedad en cada elemento de la colección DataForTheListBox

// in ViewModel class foreach(var x in this.DataForTheListBox) { x.AllComboboxItems = this.DataForTheComboBoxList; }

Luego de regreso a tu XAML:

<DataTemplate x:Key="ListBoxItemTemplate"> ... <Combobox ItemsSource="{Binding AllComboboxItems}" SelectedItem="{Binding CurrentBlah}"/> </DataTemplate>

No olvide que para que el cuadro combinado muestre correctamente el elemento actual, el elemento seleccionado debe hacer referencia al elemento real en ItemsSource del cuadro combinado. Si está obteniendo datos de un servicio web que tiene ID u objetos para representar el elemento para el cuadro combinado, debe volver a referenciarlos para que apunten a la colección real.

En Silverlight 2 estoy usando un control de usuario que hereda el contexto de datos de la página en la que está incrustado. Este contexto de datos contiene texto de pregunta, un tipo de pregunta y una colección de respuestas. En el control del usuario hay un cuadro de lista que está vinculado a la colección de respuestas. Como se muestra abajo:

<ListBox DataContext="{Binding}" x:Name="AnswerListBox" ItemContainerStyle="{StaticResource QuestionStyle}" Grid.Row="1" Width="Auto" Grid.Column="2" ItemsSource="{Binding Path=AnswerList}" BorderBrush="{x:Null}" />

Este cuadro de lista tiene un estilo asociado para mostrar las respuestas en forma de botones de opción o casillas de verificación (que me gustaría ocultar o mostrar según el tipo de pregunta) como:

<Style TargetType="ListBoxItem" x:Key="QuestionStyle"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <StackPanel Background="Transparent" > <RadioButton Visibility="{Binding Path=QuestionType, Converter={StaticResource QuestionTypeConverter}, ConverterParameter=''RadioButtonStyle''}" Height="auto" Margin="0,0,0,10" IsChecked="{TemplateBinding IsSelected}" IsHitTestVisible="False" Content="{Binding Path=AnswerText}"> </RadioButton> <CheckBox Visibility="{Binding Path=QuestionType, Converter={StaticResource QuestionTypeConverter}, ConverterParameter=''CheckBoxStyle''}" Height="auto" Margin="0,0,0,10" Content="{Binding Path=AnswerText}"> </CheckBox> </StackPanel> </ControlTemplate> </Setter.Value> </Setter> </Style>

Entonces mi pregunta es: ¿cómo accedes al contexto de datos padre para obtener el QuestionType (ya que esta es una propiedad en el contexto de datos de control del usuario, no una propiedad en un AnswerItem en la AnswerList)?

Alternativamente, ¿existe una mejor manera de cambiar estilos dinámicamente en el xaml en función de un valor de enlace?


En Silverlight 3 y versiones posteriores puede usar el enlace Elemento a Elemento y señalar los controles DataContext y algunas propiedades en mi ejemplo, su propiedad Threshold.

Así que nombre su control (por ejemplo en mi ejemplo es x: Name = "control")

<UserControl x:Class="SomeApp.Views.MainPageView" x:Name="control" >

luego dentro de este control en su ListBox ItemTemplate puede acceder al DataContext padre de esta manera:

<ListBox ItemsSource="{Binding Path=SomeItems}" > <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding ElementName=control, Path=DataContext.Threshold}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>


Una de las mejores cosas que puedes hacer con silverlight es usar el atributo Tag para almacenar una referencia al objeto al que está vinculado.

Primero, en su clase, declare una propiedad como esta

public IMyObject Current { get {return this;} }

Luego, en el control que genera el evento, puede obtener una referencia al objeto

var fe= (FrameworkElement) sender; var src = fe.Tag as IMyObject;

Entonces, ahora que tengo el objeto, es razonable que un objeto tenga referencia a su padre, entonces se une a

Current.Parent.QuestionType