none
Problemas XElement Click RRS feed

  • Pregunta

  • Hola, estoy programando una serie de botones en xaml para una aplicacion que se generan en tiempo de ejecución, el nombre lo lee de la base de datos y el estilo lo lee de un style que he predefinido en el UserControl.

    El problema esta en que los botones para generarlos en tiempo de ejecucion y poder hacerlos lo más dinámicos los defino como un XElement y a la hora programarles el evento click como se genera en un xaml normal me produce un error y no se como hacer para invocar la funcion BotonClick.

    la estructura del boton es esta:

    dim boton As XElement

    boton = <Button Cursor="Hand" Height="30" Style="{DynamicResource estiloBoton}" Click=¿? ><%= nomElemento %></Button>

     

    No se si me habré explicado bien... ¡Muchas gracias por adelantado!

    jueves, 28 de abril de 2011 11:42

Respuestas

  • Hola a todos de nuevo!

    El problema ya lo tengo solucionado, os digo la solución por si a alguien le pasa.

    Lo dejo todo conforme esta, es decir en el UserControl tengo:

    <UserControl x:Class="wpfMenu"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 mc:Ignorable="d"
                 d:DesignHeight="200" d:DesignWidth="100">

      <UserControl.Resources>

                <Style x:Key="estiloBoton" TargetType="Button">....</Style>

       </UserControl.Resources>                                                                                                                                                                                              <StackPanel Name="panelMenu" ButtonBase.Click="BotonClick"></StackPanel>
    </UserControl>

     

    Y ahora en el código creo botones de forma dinamica con un foreach

     ForEach....

     ...

    Dim boton = <Button ....>...</Button>

    panelMenu.Children.Add(CType(XamlReader.Load(boton.CreateReader),UIElement)

     

    y despues en la funcion que recoge el evento click del stackpanel genero un nuevo boton para trabajar con el:

     

    Private Sub BotonClick(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

            Dim b As System.Windows.Controls.Button = CType(e.OriginalSource, System.Windows.Controls.Button)

            MsgBox(b.Content)

     End Sub

    Y así ya funciona ¡correctamente!

    Un saludo!


    • Marcado como respuesta Fuentes010 viernes, 29 de abril de 2011 10:01
    viernes, 29 de abril de 2011 10:01

Todas las respuestas

  • Hola te voy a poner un ejemplo completo sobre esto:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Markup;
    
    namespace testsl
    {
      public partial class MainPage : UserControl
      {
        public MainPage()
        {
          InitializeComponent();
          this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
    
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
          string xaml =
    "<Grid Margin='10' " +
       "xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "+
       "xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' >"+
      "<Grid.ColumnDefinitions>" +
        "<ColumnDefinition Width='100' />" +
        "<ColumnDefinition Width='*' />" +
      "</Grid.ColumnDefinitions>" +
    
      "<Grid.RowDefinitions>" +
        "<RowDefinition Height='Auto' />" +
        "<RowDefinition Height='Auto' />" +
        "<RowDefinition Height='Auto' />" +
        "<RowDefinition Height='*' />" +
      "</Grid.RowDefinitions>" +
    
      "<TextBlock Text='First Name' Height='19' Margin='0,7,31,4' />" +
      "<TextBox x:Name='FirstName' Margin='3' Grid.Row='0' Grid.Column='1' />" +
    
      "<TextBlock Text='Last Name' Margin='0,7,6,3' Grid.Row='1' Height='20' />" +
      "<TextBox x:Name='LastName' Margin='3' Grid.Row='1' Grid.Column='1' />" +
    
      "<TextBlock Text='Date of Birth' Grid.Row='2' Margin='0,9,0,0' Height='21' />" +
      
    
      "<Button x:Name='SubmitChanges' Grid.Row='3' Grid.Column='3' " +
        "HorizontalAlignment='Right' VerticalAlignment='Top' " +
        "Margin='3' Width='80' Height='25' Content='Save' />" +
    "</Grid>";
    
    
          UIElement tree = (UIElement)XamlReader.Load(xaml);
    
          LayoutRoot.Children.Add(tree);
          Button b = LayoutRoot.Children.OfType<Grid>().First().Children.OfType<Button>().First() as Button;
          b.Click += ((s, e1) => {
            MessageBox.Show("Ok");
          });
        }
      }
    }
    
    

    Como vez mediante Linq le hacemos un query al Layout principal, como sabemos que se agregó un objeto tipo Grid, entonces lo recuperamos y immediatamente hacemos el siguiente Query para recuperar el primer botón, luego le agregamos el Handler y listo, lo he probado y corre muy bien

    Saludos espero sirva


    Ingphillip's Prog
    New Post System.Reflection

    No uses el copy-paste, No es nada sano ni recomendable....


    Si las respuestas son de utilidad y/o responden a tus preguntas es bueno para los foros marcarlas como tal.

    • Propuesto como respuesta Felipe Sotelo S jueves, 28 de abril de 2011 16:35
    jueves, 28 de abril de 2011 16:35
  • Hola Felipe ¡muchas gracias! pero mi problema esta en que yo tengo un formulario que tiene un ElementHost en el que he hospedo el userControl, en formulario desde un menuItems dependiendo de cual haya sido clicado, llamo al usercontrol para que me carge dinámicamente un stackpannel lleno de botones con submenu de ese ítem, (Eso ya funciona correctamente) los botones los cargo así:


    Dim boton = <Button Cursor="Hand" Height="30" Style="{DynamicResource estiloBoton}"><%= nomElemento %></Button>

    stackpannelMenu.Children.Add(CType(XamlReader.Load(boton.CreateReader()), UIElement))

    El problema esta en que quiero programar el click ahí en los atributos del boton, al igual que cuando programas un boton normal, en xaml.


    Si le añado el evento click al stackpannel con ButtonBase.Click = "botonClick" me funciona pero no distingue que boton ha hecho el click y necesito que lo distinga para volver a cargar más cosas dependiendo de que boton sea.
    No se si me habré explicado y tampoco si sera correcto mi planteamiento.
    ¡Muchas gracias!

    viernes, 29 de abril de 2011 8:09
  • Hola a todos de nuevo!

    El problema ya lo tengo solucionado, os digo la solución por si a alguien le pasa.

    Lo dejo todo conforme esta, es decir en el UserControl tengo:

    <UserControl x:Class="wpfMenu"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 mc:Ignorable="d"
                 d:DesignHeight="200" d:DesignWidth="100">

      <UserControl.Resources>

                <Style x:Key="estiloBoton" TargetType="Button">....</Style>

       </UserControl.Resources>                                                                                                                                                                                              <StackPanel Name="panelMenu" ButtonBase.Click="BotonClick"></StackPanel>
    </UserControl>

     

    Y ahora en el código creo botones de forma dinamica con un foreach

     ForEach....

     ...

    Dim boton = <Button ....>...</Button>

    panelMenu.Children.Add(CType(XamlReader.Load(boton.CreateReader),UIElement)

     

    y despues en la funcion que recoge el evento click del stackpanel genero un nuevo boton para trabajar con el:

     

    Private Sub BotonClick(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

            Dim b As System.Windows.Controls.Button = CType(e.OriginalSource, System.Windows.Controls.Button)

            MsgBox(b.Content)

     End Sub

    Y así ya funciona ¡correctamente!

    Un saludo!


    • Marcado como respuesta Fuentes010 viernes, 29 de abril de 2011 10:01
    viernes, 29 de abril de 2011 10:01