wpf binding listbox selecteditem

Enlace de WPF a Listbox selectedItem



binding (5)

Dentro de la DataTemplate está trabajando en el contexto de una Rule , por eso no puede enlazar con SelectedRule.Name : no hay tal propiedad en una Rule . Para enlazar con el contexto de datos original (que es su ViewModel) puede escribir:

<TextBlock Text="{Binding ElementName=lbRules, Path=DataContext.SelectedRule.Name}" />

ACTUALIZACIÓN: con respecto al enlace de propiedad SelectedItem, parece perfectamente válido, intenté lo mismo en mi máquina y funciona bien. Aquí está mi aplicación de prueba completa:

XAML:

<Window x:Class="TestWpfApplication.ListBoxSelectedItem" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="ListBoxSelectedItem" Height="300" Width="300" xmlns:app="clr-namespace:TestWpfApplication"> <Window.DataContext> <app:ListBoxSelectedItemViewModel/> </Window.DataContext> <ListBox ItemsSource="{Binding Path=Rules}" SelectedItem="{Binding Path=SelectedRule, Mode=TwoWay}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="Name:" /> <TextBox Text="{Binding Name}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Window>

Código detrás:

namespace TestWpfApplication { /// <summary> /// Interaction logic for ListBoxSelectedItem.xaml /// </summary> public partial class ListBoxSelectedItem : Window { public ListBoxSelectedItem() { InitializeComponent(); } } public class Rule { public string Name { get; set; } } public class ListBoxSelectedItemViewModel { public ListBoxSelectedItemViewModel() { Rules = new ObservableCollection<Rule>() { new Rule() { Name = "Rule 1"}, new Rule() { Name = "Rule 2"}, new Rule() { Name = "Rule 3"}, }; } public ObservableCollection<Rule> Rules { get; private set; } private Rule selectedRule; public Rule SelectedRule { get { return selectedRule; } set { selectedRule = value; } } } }

¿Puede alguien ayudar con lo siguiente? Estar jugando con esto, pero no puedo, por mi vida, hacer que funcione.

Tengo un modelo de vista que contiene las siguientes propiedades;

public ObservableCollection<Rule> Rules { get; set; } public Rule SelectedRule { get; set; }

En mi XAML tengo;

<ListBox x:Name="lbRules" ItemsSource="{Binding Path=Rules}" SelectedItem="{Binding Path=SelectedRule, Mode=TwoWay}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="Name:" /> <TextBox x:Name="ruleName"> <TextBox.Text> <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" /> </TextBox.Text> </TextBox> </StackPanel> </DataTemplate> </ListBox.ItemTemplate>

Ahora, el ItemsSource funciona bien y obtengo una lista de objetos de Reglas con sus nombres mostrados en lbRules.

El problema que tengo es vincular la propiedad SelectedRule con SelectedItem de lbRules. Intenté enlazar la propiedad de texto de un bloque de texto a SelectedRule pero siempre es nula.

<TextBlock Text="{Binding Path=SelectedRule.Name}" />

El error que veo en la ventana de resultados es: Error de ruta de BindingExpression: no se encontró la propiedad ''SelectedRule''.

¿Puede alguien ayudarme con este enlace? No puedo ver por qué no debería encontrar la propiedad SelectedRule.

Luego intenté cambiar la propiedad de texto del bloque de texto como a continuación, que funciona. El problema es que quiero usar el SelectedRule en mi ViewModel.

<TextBlock Text="{Binding ElementName=lbRules, Path=SelectedItem.Name}" />

Muchas gracias por su ayuda.


En primer lugar, debe implementar la interfaz INotifyPropertyChanged en su modelo de vista y elevar el evento PropertyChanged en el setter de la propiedad Rule . De lo contrario, ningún control que se enlace a la propiedad SelectedRule se "sabrá" cuando se haya cambiado.

Entonces, tu XAML

<TextBlock Text="{Binding Path=SelectedRule.Name}" />

es perfectamente válido si este TextBlock está fuera del ItemTemplate del ListBox y tiene el mismo DataContext que el ListBox .


Para mí, normalmente uso DataContext para enlazar propiedades de dos profundidades como esta pregunta.

<TextBlock DataContext="{Binding SelectedRule}" Text="{Binding Name}" />

O, prefiero usar ElementName porque solo logra enlaces con controles de vista.

<TextBlock DataContext="{Binding ElementName=lbRules, Path=SelectedItem}" Text="{Binding Name}" />


Yocoder tiene razón,

Dentro de DataTemplate , su DataContext se establece en la Rule está manejando actualmente.

Para acceder al DataContext los padres, también puede considerar el uso de un RelativeSource en su enlace:

<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ____Your Parent control here___ }}, Path=DataContext.SelectedRule.Name}" />

Más información sobre RelativeSource se puede encontrar aquí:

http://msdn.microsoft.com/en-us/library/system.windows.data.relativesource.aspx


ya que configura su fuente de elementos para su colección, su cuadro de texto está vinculado a cada elemento individual de esa colección. la propiedad del elemento seleccionado es útil en este escenario si intentaba hacer un formulario de detalles maestros, con 2 cuadros de lista. vincularía la fuente de elementos del segundo cuadro de lista a la colección secundaria de reglas. en otras palabras, el elemento seleccionado alerta sobre los controles externos de que su fuente ha cambiado, los controles internos (aquellos que están dentro de su plantilla de datos ya son conscientes del cambio).

y para responder a su pregunta, sí, en la mayoría de las circunstancias, establecer la fuente de elementos es lo mismo que configurar el contexto de datos del control.