Foros del Web » Programación para mayores de 30 ;) » .NET »

Evento wpf

Estas en el tema de Evento wpf en el foro de .NET en Foros del Web. Hola a todos necesito vustra ayuda, estoy generando una mini aplicación con WPF y he creado este listbox después de mucho esfuerzo. <ListBox Height="189" x:Name="lst" ...
  #1 (permalink)  
Antiguo 15/02/2017, 14:29
 
Fecha de Ingreso: julio-2008
Mensajes: 134
Antigüedad: 8 años, 7 meses
Puntos: 1
Sonrisa Evento wpf

Hola a todos necesito vustra ayuda, estoy generando una mini aplicación con WPF y he creado este listbox después de mucho esfuerzo.

<ListBox Height="189" x:Name="lst" Margin="0,0,350,0" Background="DarkSeaGreen" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Width="150" Height="35" HorizontalAlignment="Left" Name="cat" Margin="0" Click="Button_Click" >
<Button.Content>
<StackPanel Name="Lst_Stack" Orientation="Horizontal" HorizontalAlignment="Left">
<Image Source="{Binding foto}" Height="40" Width="40" />
<TextBlock Text="{Binding nom}" Margin="5"/>
</StackPanel>

</Button.Content>
</Button>

</StackPanel>

</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>



Resumen del código, es un listbox con un template, donde este template tiene un button. Este button tiene un stackPanel y dentro de este un image y un textblock.

Algo retorcido lo se.

Mi duda es, al apretar a uno de los botones del listbox como puedo obtener el texto del textblock que tiene asignado?

Porque cada textblock es diferente ya que se rellena segun un binding de la base de datos

Si capturo el objeto button no se como acceder a la jerarquía.
Alguna sujerencia?
Estoy haciendo la aplicación con c#
  #2 (permalink)  
Antiguo 16/02/2017, 14:53
Avatar de Drako_18  
Fecha de Ingreso: mayo-2005
Ubicación: Madrid
Mensajes: 458
Antigüedad: 11 años, 9 meses
Puntos: 7
Respuesta: Evento wpf

Buenas compañero,

Si asignas un ID a los elementos que quieres acceder (textblock), con hacer un find de los controles que tiene dentro... Será suficiente....


Un saludo!
__________________
Rubén Espada Bernal
Analista Programador VB.Net (entorno web y escritorio)
  #3 (permalink)  
Antiguo 17/02/2017, 04:28
 
Fecha de Ingreso: enero-2015
Mensajes: 322
Antigüedad: 2 años, 1 mes
Puntos: 47
Respuesta: Evento wpf

Cita:
Iniciado por Drako_18 Ver Mensaje
Buenas compañero,

Si asignas un ID a los elementos que quieres acceder (textblock), con hacer un find de los controles que tiene dentro... Será suficiente....


Un saludo!
Por supuesto que esta información es totalmente incorrecta.

En primer lugar en WPF los elementos no tienen "Id", sino que tienen un x:Name.

En segundo lugar, no se puede referenciar por x:Name los UIElements dentro de un DataTemplate asignado como ItemTemplate de un ItemsControl.

Encima de todo, como se esta usando DataBinding, hay un error conceptual en querer acceder a los datos a traves de los UIElements, ya que en realidad los datos se encuentran fuera de la GUI, en el objeto que se usa como DataContext.

En este caso, una forma correcta de resolverlo es hacer algo como esto:

Código C#:
Ver original
  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3.     var source = (FrameworkElement)sender;
  4.     var data = sender.DataContext as MiClase;
  5.  
  6.     var nom = data.nom;
  7.     var foto = data.foto;
  8. }

Donde MiClase es la clase que se está usando como elemento de la lista.

Otra forma aún más correcta es separar estrictamente el comportamiento de la capa de presentación, de la parte visual de la capa de presentación, usando el patrón MVVM o Presentation Model. En WPF, para usar este patrón en interacciones del usuario (como clicks de botones) se utiliza la interfaz System.Windows.Input.ICommand, con alguna de las muchas implementaciones que hay en los distintos frameworks MVVM que existen.

Última edición por agleiva; 17/02/2017 a las 04:34
  #4 (permalink)  
Antiguo 17/02/2017, 11:29
 
Fecha de Ingreso: julio-2008
Mensajes: 134
Antigüedad: 8 años, 7 meses
Puntos: 1
Respuesta: Evento wpf

Gente he hecho esto haber que os parece

Button mouseWasDownOn = (Button) e.Source ; //Capturo el objeto en este caso un botón


StackPanel Sp = (StackPanel)mouseWasDownOn.Content; // del boton extraigo el StackPanel


TextBlock tb = (TextBlock)Sp.Children[2]; // Del StackPanel el textblock que es lo que me interesa, este está en la posición 2
MessageBox.Show(tb.Text); //Saco el mensaje por pantalla.


Supongo que habrá formas mas elegantes y mejores.

Que os parece?

Estudiaré las vuestras haber que tal.
  #5 (permalink)  
Antiguo 17/02/2017, 15:42
 
Fecha de Ingreso: enero-2015
Mensajes: 322
Antigüedad: 2 años, 1 mes
Puntos: 47
Respuesta: Evento wpf

Cita:
Iniciado por sacris1 Ver Mensaje
Gente he hecho esto haber que os parece
El problema con hacer eso es que tu codigo esta completamente atado a la estructura de la GUI:

Tu codigo espera:
1 - Que el evento sea invocado por un Button (que no es el unico UIElement que soporta el evento Click)
2 - Que el Content del Button sea un StackPanel.
3 - Que el StackPanel tenga al menos 3 logical childs.
4 - Que el 3er logical child del StackPanel sea un TextBlock.

Si cualquiera de los puntos anteriores no fuese cierto en tiempo de ejecución (cosa que puede ocurrir fácilmente si se decidiera darle un estilo visual diferente a la GUI) tu código dejaría de funcionar.
Esto hace que tu código sea muy frágil, como ves. Es por eso que es recomendable un approach mucho más desacoplado.

En contraste, mi código (en la respuesta anterior) espera:

1 - Que el evento sea invocado por un FrameworkElement (esto incluye cualquier elemento visual con interactividad, no limitado a un Button)
2 - Que el DataContext de dicho FrameworkElement sea un objeto de tipo MiClase (puesta como ejemplo), que siempre va a ser cierto mientras el evento sea disparado desde cualquier elemento que esté dentro del ListBox.ItemTemplate

Como ves, mi código tiene muchas menos "expectativas" o requisitos para funcionar, abarca una mayor cantidad de casos (soportando cualquier elemento y no solo Button), y NO depende de la disposición visual de los elementos. Esto hace que el código sea más robusto y menos propenso a errores.
  #6 (permalink)  
Antiguo 18/02/2017, 13:35
 
Fecha de Ingreso: julio-2008
Mensajes: 134
Antigüedad: 8 años, 7 meses
Puntos: 1
Respuesta: Evento wpf

Hola Agleiva voy a probar tu código, una cosa,
la línia está: var data = sender.DataContext as MiClase; no me la reconoce como buena.
MiClase en mi caso es un dataset con un datatable llamado artículo.

La lista la lleno así: this.lst.ItemsSource = ds.articulos;

pero sender.DataContext me dice que no existe.

Lo siento pero no hace mucho que estoy aprendiendo wpf + c#
Si me pudieses explicar un poco esto del datacontext estaría genial.
Muchas gracias
  #7 (permalink)  
Antiguo 18/02/2017, 14:59
 
Fecha de Ingreso: enero-2015
Mensajes: 322
Antigüedad: 2 años, 1 mes
Puntos: 47
Respuesta: Evento wpf

Cita:
Iniciado por sacris1 Ver Mensaje
Hola Agleiva voy a probar tu código, una cosa,
la línia está: var data = sender.DataContext as MiClase; no me la reconoce como buena.
MiClase en mi caso es un dataset con un datatable llamado artículo.

La lista la lleno así: this.lst.ItemsSource = ds.articulos;

pero sender.DataContext me dice que no existe.

Lo siento pero no hace mucho que estoy aprendiendo wpf + c#
Si me pudieses explicar un poco esto del datacontext estaría genial.
Muchas gracias
Error mio, perdon.

Es source.DataContext, ya que sender es tipo Object y source es de tipo FrameworkElement.

Lo del DataSet desconozco, no trabajo con esa API ya que se dejó de usar hace casi 10 años, en favor de armar modelos estáticamente tipados.
  #8 (permalink)  
Antiguo 18/02/2017, 15:55
 
Fecha de Ingreso: julio-2008
Mensajes: 134
Antigüedad: 8 años, 7 meses
Puntos: 1
Respuesta: Evento wpf

Agleiva, podrias explicar a que te refieres con esto de modelos estáticamente tipados?
  #9 (permalink)  
Antiguo 19/02/2017, 08:38
 
Fecha de Ingreso: enero-2015
Mensajes: 322
Antigüedad: 2 años, 1 mes
Puntos: 47
Respuesta: Evento wpf

Por modelo estático me refiero a un conjunto de clases que representan los registros de tu base de datos y que contienen propiedades que representan las columnas y relaciones de la misma.

Por ejemplo:

Dada la siguiente tabla "Personas":

Código Tabla:
Ver original
  1. Id     Nombre      Apellido
  2. 1       Juan         Perez
  3. 2       Pedro        Rodriguez
Uno podria crear la clase:

Código C#:
Ver original
  1. public class Persona
  2. {
  3.     public int Id {get;set;}
  4.     public string Nombre {get;set;}
  5.     public string Apellido {get;set;}
  6. }
Y asi sucesivamente. El problema con la API de DataSet / DataTable es que es "stringly typed" (http://wiki.c2.com/?StringlyTyped) en lugar de Strongly typed.
Los frameworks de acceso a datos modernos como Entity Framework o NHibernate resuelven este problema, permitiendo incluso realizar consultas de manera tipada mediante LINQ, por ejemplo.



La zona horaria es GMT -6. Ahora son las 01:44.