none
Usercontrol Dinamico RRS feed

  • Pregunta

  • Hola amigos.

    tengo el siguiente problemilla: he creado un user control el cual contiene un listbox que se llena apartir de una tabla llamada formulas, en la tabla hay 4 tipos de formulas, yo necesito llamar este usercontrol desde varios lugares de mi aplicacion y dependiendo del lugar de donde lo llame dependera de que tipo de formulas se llene y de igualforma a que campo esta asociado segun el modelo de Bd, me explico: la tabla formulas tiene relacion con la tabla tareas, la cual tiene 4 campos con los cuales se relaciona con formulas con el idformula.

    cuando la formula es tipo 1 la relacion es: => Formula.Idformula  con Tarea.IdFormulaCache

    cuando la formula es tipo 2 la relacion es: => Formula.Idformula  con Tarea.IdFormulaComando

    cuando la formula es tipo 3 la relacion es: => Formula.Idformula  con Tarea.IdFormulaCola

    cuando la formula es tipo 4 la relacion es: => Formula.Idformula  con Tarea.IdFormulaDocumento

     

    cuando hace focus el usercontrol debe mostrar la formula que esta selecciona segun el campo de la tabla tarea.

    Actualmente lo he hecho para cuando el campo es IdFormulaChache, pero no se como desirle al Bingdin que identifique si es IdFormulaCola, IdFormulaDocumento, IdFormulaCahe o IdFormulaCola. para las consultas por tipo no hay problema el problema es en binding

    este es el XAML actual como dije antes funciona con IdFormulaChache.

    <UserControl x:Class="MantizOnline40.Modeler.Views.SeleccionarFormulaView"
           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" 
           xmlns:ig="http://schemas.infragistics.com/xaml"
           mc:Ignorable="d" Name="seleccionarFormulaView">
      <Grid>
        <Grid.ColumnDefinitions >
          <ColumnDefinition />      
        </Grid.ColumnDefinitions>
        <ListBox Name="lbxFormulas" SelectedValuePath ="IdFormula" DisplayMemberPath="Descripcion" Focusable="True" 
             SelectedValue ="{Binding Path=IdFormulaCache, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
          <ListBox.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
              <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                  <Setter Property="Foreground" Value="Red"/>
                </Trigger>
              </Style.Triggers>
            </Style>
          </ListBox.Resources>
        </ListBox>       
       </Grid>
    </UserControl>
    
    
    Como pueden ver la linea del SelelctedValue hace bindig con IdFormulaCahe, como hacer para que identifique y lo haga con el resto.
    jueves, 6 de enero de 2011 0:33

Respuestas

  • Hola Wipito.

    La verdad es que no entiendo muy bien que quieres hacer, asi que vamos a intentar aclararlo.

    1 UserControl que se incrusta en varias paginas (entiendo que nunca existiran 2 Usercontrol en una misma pagina).

    Hay que buscar un punto de inflexion para poder seleccionar una u otra formula a mostrar y este puede ser la pagina o el control contenedor, ya que tendran diferentes nombres para cada pagina supongo.

    Se puede realizar de varias formas (como siempre), las 2 mas basicas que se me ocurren son:

    1.- Heredar de ListBox y personalizarlo.

    2.- hacer uso de un Conversor en el Binding.

    El uso de la herencia, a no ser que quieras realizar algo mas complejo, yo lo descartaria, ademas parece ser que tu unico problema es el binding, con lo que parece la mejor solucion a simple vista.

    La idea del converter es la que se muestra en la siguiente pagina (a modo de ejemplo)

    http://blogs.msdn.com/b/bencon/archive/2006/05/10/594886.aspx

    Si es algo como esto lo que buscas, comentalo e intentamos ir por ahi.

     


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/
    • Propuesto como respuesta CorsarioVasco martes, 11 de enero de 2011 17:50
    • Marcado como respuesta Wipito miércoles, 12 de enero de 2011 17:48
    jueves, 6 de enero de 2011 19:55

Todas las respuestas

  • Hola Wipito.

    La verdad es que no entiendo muy bien que quieres hacer, asi que vamos a intentar aclararlo.

    1 UserControl que se incrusta en varias paginas (entiendo que nunca existiran 2 Usercontrol en una misma pagina).

    Hay que buscar un punto de inflexion para poder seleccionar una u otra formula a mostrar y este puede ser la pagina o el control contenedor, ya que tendran diferentes nombres para cada pagina supongo.

    Se puede realizar de varias formas (como siempre), las 2 mas basicas que se me ocurren son:

    1.- Heredar de ListBox y personalizarlo.

    2.- hacer uso de un Conversor en el Binding.

    El uso de la herencia, a no ser que quieras realizar algo mas complejo, yo lo descartaria, ademas parece ser que tu unico problema es el binding, con lo que parece la mejor solucion a simple vista.

    La idea del converter es la que se muestra en la siguiente pagina (a modo de ejemplo)

    http://blogs.msdn.com/b/bencon/archive/2006/05/10/594886.aspx

    Si es algo como esto lo que buscas, comentalo e intentamos ir por ahi.

     


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/
    • Propuesto como respuesta CorsarioVasco martes, 11 de enero de 2011 17:50
    • Marcado como respuesta Wipito miércoles, 12 de enero de 2011 17:48
    jueves, 6 de enero de 2011 19:55
  • Hola David Gracias por contestar.

    te voy a intentar explicar esta parte de la aplicacion.

    Existe una parte de la aplicacion que se llama Administrar Tareas, esta consta de un TabControl con 4 tabs, para 4 tipos de tareas los cuales son los mismos de las formulas, es decir, el header de cada Tab es: Tarea Tipo Cola, Tarea Tipo Cache, Tarea Tipo Documento, Tarea Tipo Comando.

    cuando estas creando algun tipo de tarea, existe un Checbox, que dice algo asi como "Ejecutar si cumple la Condicion" si seleccionas el check, en ese momento se hace el llamado al UserControl, el cual debe mostrar las Formulas filtradas segun el tipo de tarea que estas creando.

    Ejemplo1: si estoy creando una Tarea Tipo Cache, y selecciono el check de "Ejecutar si cumple la Condicion" me debe mostrar las formulas que son de TipoCache(tipo=1), cuando ejecuto el boton de guardar tarea  el Id de la formula seleccionada (IdFormula), se guarda en el campo IdFormulaCache de mi tabla tareas.

    Ejemplo2: si estoy creando una Tarea Tipo Comando, y selecciono el check de "Ejecutar si cumple la Condicion" me debe mostrar las formulas que son de TipoComando(tipo=2), cuando ejecuto el boton de guardar tarea  el Id de la formula seleccionada (IdFormula), se guarda en el campo IdFormulaComando de la tabla tareas.

    Ejemplo3: si estoy creando una Tarea Tipo Cola, y selecciono el check de "Ejecutar si cumple la Condicion" me debe mostrar las formulas que son de TipoCola(tipo=3), cuando ejecuto el boton de guardar tarea  el Id de la formula seleccionada (IdFormula), se guarda en el campo IdFormulaCola de la tabla tareas.

    Ejemplo4: si estoy creando una Tarea Tipo Documento, y selecciono el check de "Ejecutar si cumple la Condicion" me debe mostrar las formulas que son de TipoDocumento(tipo=4), cuando ejecuto el boton de guardar tarea  el Id de la formula seleccionada (IdFormula), se guarda en el campo IdFormulaDocumento de mi tabla tareas.

    En el momento que quiera consultar una tarea ya creada y almacenada en BD, me debe mostrar el Check de "Ejecutar si cumple la Condicion" seleccionado (claro en caso que lo hubiera seleccionado al momento de crearla) como este check esta seleccionado, entonces me debe mostrar las formulas segun el tipo de tarea que este consultando, y me debe dejar ver que formula es la seleccionada(en mi caso la estoy dejando en rojo)  

    En tu respuesta tienes razon, no existira 2 veces el usercontol en un mismo Tab. y la forma con la que identifica que formula llamar es mediante el check ya que se llaman diferente y en el evento click le envio por parametro al contructor de usercontrol el tipo de la formula a cargar.

    Espero esto te oriente mejor.

    Aca los eventos para Tarea Tipo Cache.

    private void cbxCondicioncache_Checked(object sender, RoutedEventArgs e)
        {
          cbxCondicioncache.Cursor = System.Windows.Input.Cursors.Wait;
          Byte tipoDato = 1;
          if ((bool)cbxCondicioncache.IsChecked)
          {
            SeleccionarFormulaView seleccionarformula = new SeleccionarFormulaView(tipoDato);
            dockFormulas.Children.Add(seleccionarformula);
            gbxformulas.Visibility = System.Windows.Visibility.Visible;
          }
          cbxCondicioncache.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    
        private void cbxCondicioncache_Click(object sender, RoutedEventArgs e)
        {
          cbxCondicioncache.Cursor = System.Windows.Input.Cursors.Wait;     
          Byte tipoDato = 1;
          if ((bool)cbxCondicioncache.IsChecked)
          {
            if (dockFormulas.Children.Count > 0)
            {
              cbxCondicioncache.Cursor = System.Windows.Input.Cursors.Arrow;
              return;
            }
            SeleccionarFormulaView seleccionarformula = new SeleccionarFormulaView(tipoDato);
            dockFormulas.Children.Add(seleccionarformula);
            gbxformulas.Visibility = System.Windows.Visibility.Visible;
          }
          else
          {
            dockFormulas.Children.Clear();
            gbxformulas.Visibility = System.Windows.Visibility.Hidden;
          }
          cbxCondicioncache.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    

    Aca los eventos para Tarea Tipo Cola.

    private void cbxCondicioncola_Checked(object sender, RoutedEventArgs e)
        {
          cbxCondicioncola.Cursor = System.Windows.Input.Cursors.Wait;
          Byte tipoDato = 3;
          if ((bool)cbxCondicioncola.IsChecked)
          {
            SeleccionarFormulaView seleccionarformula = new SeleccionarFormulaView(tipoDato);
            dockFormulascola.Children.Add(seleccionarformula);
            gbxformulascola.Visibility = System.Windows.Visibility.Visible;
          }
          cbxCondicioncola.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    
        private void cbxCondicioncola_Click(object sender, RoutedEventArgs e)
        {
          cbxCondicioncola.Cursor = System.Windows.Input.Cursors.Wait;     
          Byte tipoDato = 3;
          if ((bool)cbxCondicioncola.IsChecked)
          {
            if (dockFormulascola.Children.Count > 0)
            {
              cbxCondicioncola.Cursor = System.Windows.Input.Cursors.Arrow;
              return;
            }
            SeleccionarFormulaView seleccionarformula = new SeleccionarFormulaView(tipoDato);
            dockFormulascola.Children.Add(seleccionarformula);
            gbxformulascola.Visibility = System.Windows.Visibility.Visible;
          }
          else
          {
            dockFormulascola.Children.Clear();
            gbxformulascola.Visibility = System.Windows.Visibility.Hidden;
          }
          cbxCondicioncola.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    

    Aca los eventos para Tarea Tipo Comando.

    private void cbxCondicioncomando_Checked(object sender, RoutedEventArgs e)
        {
          cbxCondicioncomando.Cursor = System.Windows.Input.Cursors.Wait;
          Byte tipoDato = 2;
          if ((bool)cbxCondicioncomando.IsChecked)
          {
            SeleccionarFormulaView seleccionarformula = new SeleccionarFormulaView(tipoDato);
            dockFormulascomando.Children.Add(seleccionarformula);
            gbxformulascomando.Visibility = System.Windows.Visibility.Visible;
          }
          cbxCondicioncomando.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    
        private void cbxCondicioncomando_Click(object sender, RoutedEventArgs e)
        {
          cbxCondicioncomando.Cursor = System.Windows.Input.Cursors.Wait;     
          Byte tipoDato = 2;
          if ((bool)cbxCondicioncomando.IsChecked)
          {
            if (dockFormulascomando.Children.Count > 0)
            {
              cbxCondicioncomando.Cursor = System.Windows.Input.Cursors.Arrow;
              return;
            }
            SeleccionarFormulaView seleccionarformula = new SeleccionarFormulaView(tipoDato);
            dockFormulascomando.Children.Add(seleccionarformula);
            gbxformulascomando.Visibility = System.Windows.Visibility.Visible;
          }
          else
          {
            dockFormulascomando.Children.Clear();
            gbxformulascomando.Visibility = System.Windows.Visibility.Hidden;
          }
          cbxCondicioncomando.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    

    Aca los eventos para Tarea Tipo Documento.

    private void cbxCondiciondocumento_Checked(object sender, RoutedEventArgs e)
        {
          cbxCondiciondocumento.Cursor = System.Windows.Input.Cursors.Wait;
          Byte tipoDato = 4;
          if ((bool)cbxCondiciondocumento.IsChecked)
          {
            SeleccionarFormulaView seleccionarformula = new SeleccionarFormulaView(tipoDato);
            dockFormulasdocumento.Children.Add(seleccionarformula);
            gbxformulasdocumento.Visibility = System.Windows.Visibility.Visible;
          }
          cbxCondiciondocumento.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    
        private void cbxCondiciondocumento_Click(object sender, RoutedEventArgs e)
        {
          cbxCondiciondocumento.Cursor = System.Windows.Input.Cursors.Wait;     
          Byte tipoDato = 4;
          if ((bool)cbxCondiciondocumento.IsChecked)
          {
            if (dockFormulasdocumento.Children.Count > 0)
            {
              cbxCondiciondocumento.Cursor = System.Windows.Input.Cursors.Arrow;
              return;
            }
            SeleccionarFormulaView seleccionarformula = new SeleccionarFormulaView(tipoDato);
            dockFormulasdocumento.Children.Add(seleccionarformula);
            gbxformulasdocumento.Visibility = System.Windows.Visibility.Visible;
          }
          else
          {
            dockFormulasdocumento.Children.Clear();
            gbxformulasdocumento.Visibility = System.Windows.Visibility.Hidden;
          }
          cbxCondiciondocumento.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    

    y aca el unico y pobre XAML del usercontrol que tengo que solo funciona para las tipo Cache.

    <UserControl x:Class="MantizOnline40.Modeler.Views.SeleccionarFormulaView"
           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" 
           xmlns:ig="http://schemas.infragistics.com/xaml"
           xmlns:local="clr-namespace:MantizOnline40.Modeler.Views" 
           mc:Ignorable="d" Name="seleccionarFormulaView">
      <Grid>
        <Grid.ColumnDefinitions >
          <ColumnDefinition />      
        </Grid.ColumnDefinitions>
        <ListBox Name="lbxFormulas" SelectedValuePath ="IdFormula" DisplayMemberPath="Descripcion" Focusable="True" 
             SelectedValue ="{Binding Path=IdFormulaCache, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
          <ListBox.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
              <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                  <Setter Property="Foreground" Value="Red"/>
                </Trigger>
              </Style.Triggers>
            </Style>
          </ListBox.Resources>
        </ListBox>       
       </Grid>
    </UserControl>
    
    

    por ultimo este es el codigo del Usercontrol

    public partial class SeleccionarFormulaView : UserControl 
      {
        private byte tipoDato;
        
        public SeleccionarFormulaView(byte tipoDato)
        {
          // TODO: Complete member initialization
          InitializeComponent();
          this.tipoDato = tipoDato;
          CargarTreeViewConFormulas();
        }
    
        private void CargarTreeViewConFormulas()
        {
          List<FormulaViewModel> listaFormulas = new List<FormulaViewModel>();
          listaFormulas = MantizOnline40.Modeler.Services.AdministrationService.ObtenerFormulas();
          var F = (from fm in listaFormulas
               where fm.TipoDato == tipoDato
               select fm).ToList();
          lbxFormulas.ItemsSource = F;      
        }    
      }
    

    Bueno david Disculpame por extenderme tanto, pero quiero que me entiedas, ojola y asi sea.

    jueves, 6 de enero de 2011 22:51
  • Hola he visto que mi problema es posible solucionarlo con DataTemplateSelector, ya he creado mis template, uno para dada tipo, tambien mi clases que identifica que template retornar, pero ahora cuando se muestra se sale es la ruta del ViewModel, algo asi como MantizOnline40.Modeler.ViewModels.FormulaViewModel
    martes, 11 de enero de 2011 17:49
  • ¡Hola!

    Muy buen aporte. Para el que no lo conocía como era mi caso:

    http://msdn.microsoft.com/es-es/library/system.windows.controls.datatemplateselector.aspx

    Yeray ya lo trató en su blog en la entrada:

    http://geeks.ms/blogs/jyeray/archive/2010/11/28/wpf-plantillas-de-datos-din-225-micas.aspx

    Saludos,

    martes, 11 de enero de 2011 19:54
  • Hola todo parece ir de maravilla con los datatemplateselector. pero como siempre no falta el problemilla, y es que creo que al adicionar un recurso se pierde el datacontext, o esa es la imprecion que tengo

    aca un codigo de ejemplo que estaba realizando

     <StackPanel>
        <StackPanel.Resources >
          <local:UserTemplateSelector x:Key="FormulasTemplateSelector"/>
          <DataTemplate x:Key="DatatemplateFormulastipocache">
            <StackPanel Orientation="Horizontal" >
              <TextBlock Text="{Binding Descripcion}"/>
              <TextBlock Text=" "/>
              <TextBlock Text="("/>
              <TextBlock Text="{Binding IdFormula}"/>
              <TextBlock Text=")"/>
              <TextBlock Text="{Binding Path=IdFormulaCache}"/>          
            </StackPanel>
          </DataTemplate>
          <DataTemplate x:Key="DatatemplateFormulastipocomando">
            <StackPanel Orientation="Horizontal" >
              <TextBlock Text="{Binding Descripcion}"/>
              <TextBlock Text=" "/>
              <TextBlock Text="("/>
              <TextBlock Text="{Binding IdFormula}"/>
              <TextBlock Text=")"/>
              <TextBlock Text="{Binding Path=IdFormulaComando}"/>
            </StackPanel>
          </DataTemplate>
        </StackPanel.Resources>
    
        <ListBox ItemTemplateSelector="{StaticResource FormulasTemplateSelector}" Name="lbxFormulas">
          
        </ListBox>
    </StackPanel>
    

    el anterior es el codigo de mi ejemplo actual, pero resulta que el dato de IdFormulaCache y IdFormulaComondo, no lo imprime, mi teoria es que al poner un recurso se pieder el Datacontex, los otros dos como IdFormula y Descripcion si los imprime, estos pertenecen a una lista que es asignada al ItemSource de lbxFormulas.

    Ahora por que digo que se pierde el Datacontext, por que si quito todo el codigo anterios y dejo el  siguiente codigo si encuentra el dato:

    <ListBox Name="lbxFormulas" SelectedValuePath ="IdFormula" DisplayMemberPath="Descripcion" 
             SelectedValue="{Binding Path=IdFormulaCache, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
          <ListBox.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
              <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                  <Setter Property="Foreground" Value="Red"/>
                </Trigger>
              </Style.Triggers>
            </Style>
          </ListBox.Resources>
        </ListBox>

    en este caso si encuentra IdFormulaCache, se visuliza seleccionada la que contiene IdFormulaCache.

    mmm porque pasa eso, o en donde estoy cometiendo un error, o como le hago para que al utilizar el codigo de arriba con pierda los datos ya mensionados.

    gracias

     

    miércoles, 12 de enero de 2011 14:38
  • Bueno finalmente, lo logre con la opcion que me dio David, muchas gracias

    miércoles, 12 de enero de 2011 17:47
  • Hola Wipito.

    Siento no haberte podido ayudar mas, pero he estado enfermo y no me he podido conectar.

    Me alegro que hayas encontrado una solucion.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/
    viernes, 14 de enero de 2011 18:00