none
Databinding a Propiedad de UserControl RRS feed

  • Pregunta

  • Hola tengo un problema es que he creado un Control de usuario con una propiedad en cual ya funciona bien cuando le paso valores "a mano" pero lo que pasa es que necesito usarlo con databinding y pues me da error, y de hecho en la ventana de propiedades no me deja usar el asistente de databinding, ahora el liedo este articulo pero la soluicion ahi espuesta no me sirve porque bindable y browsable no las reconoce ya que parece que no estan disponibles para wp7.

    Hay alguna otra forma de hacerlo


    • Editado Bazookao domingo, 18 de septiembre de 2011 17:39
    domingo, 18 de septiembre de 2011 17:25

Respuestas

  • Hola MartinRomania,

    He creado un proiecto con tu código y he estado trasteando un poquito. Al final he conseguido que funcione. Pego a continuación el código C# y XAML de tu user control:

    public partial class ucPrueba : UserControl
        {
            public ucPrueba()
            {
                InitializeComponent();
            }
    
            public static readonly DependencyProperty UserControlTextProperty = DependencyProperty.Register("UserControlText", typeof(string), typeof(ucPrueba), null);
    
            public string UserControlText
            {
                get { return (string)GetValue(UserControlTextProperty); }
                set
                { SetValue(UserControlTextProperty, value); }
            }
        }


    <UserControl x:Class="PhoneApp2.ucPrueba" Name="myucPrueba"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        d:DesignHeight="480" d:DesignWidth="480" Height="74">
    
    
        <Grid x:Name="LayoutRoot" Margin="0">
            <TextBox x:Name="tbFrecuencia" TextWrapping="Wrap" Margin="0" VerticalAlignment="Top" d:LayoutOverrides="VerticalAlignment" Text="{Binding UserControlText, ElementName=myucPrueba}" />
        </Grid>
    </UserControl>


    He puesto en negrita los cambios más significativos. Como podrás observar lo que cambia es el binding a la propiedad Text del TextBox de tu UserControl. Parece ser que este binding no se hacia correctamente anteriormente, porque no cogía bien el DataContext. Poniendolo de esta forma funciona bien.

    Espero que te sirva de ayuda.


    • Editado aZubi sábado, 22 de septiembre de 2012 14:01
    • Propuesto como respuesta MartinRomania sábado, 22 de septiembre de 2012 22:29
    • Marcado como respuesta Bazookao miércoles, 26 de septiembre de 2012 16:45
    sábado, 22 de septiembre de 2012 13:56

Todas las respuestas

  • Estoy en tu misma situación. Además el enlace a http://rafavargas.com/2007/09/16/user-controls-enlazados-a-datos-data-binding-to-a-user-control/ no me funciona.

    ¿Has avanzado algo en la solución?.

    un saludo

    jueves, 20 de septiembre de 2012 21:04
  • Para que la propiedad sea bindable necesitas crear un DependencyProperty:

    public static readonly DependencyProperty TuPropiedadProperty = DependencyProperty.Register(
    "TuPropiedad", 
    typeof(double), 
    typeof(TuControl), 
    null);       
    
    public double TuPropiedad       
    {
                get { return (double)base.GetValue(TuPropiedadProperty); }
                set { base.SetValue(TuPropiedadProperty, value); }      
    }


    viernes, 21 de septiembre de 2012 13:41
  •     Hola aZubi,

    gracias por contestar. Ya pasé por ponerle una DP y me pasa como a BazooKao. Le paso el valor a mano (por ejemplo "patata") y me funciona perfectamente

    <ViewControles:ucPrueba x:Name="tbPrueba" Width="150" Margin="0"
     UserControlText="patata" >
    </ViewControles:ucPrueba>

    En cambio si le paso el valor con un Binding no aparece nada

    <ViewControles:ucPrueba x:Name="tbPrueba" Width="150" Margin="0" 
    UserControlText="{Binding NewPlanificacion.Prueba, Mode=TwoWay}" >
    </ViewControles:ucPrueba>

    Aquí pongo el código c# de mi control 

    publicpartialclass ucPrueba : UserControl
       {
            public ucPrueba()
            {
                InitializeComponent();
                this.DataContext =this;
            }

            public static readonly DependencyProperty UserControlTextProperty =DependencyProperty.Register("UserControlText", typeof (string), typeof (ucPrueba),
                                            newPropertyMetadata(string.Empty, newPropertyChangedCallback(OnUserControlTextPropertyChanged)));

            publicstring UserControlText
            {
                get { return (string)GetValue(UserControlTextProperty); }
                set
                {SetValue(UserControlTextProperty, value);}
            }

            privatestaticvoid OnUserControlTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {

    //No hago nada

    }

        }

    Y aquí el código XAML del control

    <UserControl x:Class="Prueba.ViewControles.ucPrueba"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        d:DesignHeight="480" d:DesignWidth="480" Height="74"
        DataContext = "{Binding RelativeSource={RelativeSource Self}}">

        <Grid x:Name="LayoutRoot" Margin="0">
            <TextBox x:Name="tbFrecuencia" TextWrapping="Wrap" Margin="0" VerticalAlignment="Top" d:LayoutOverrides="VerticalAlignment" Text="{Binding UserControlText}"/>

        </Grid>
    </UserControl>

    Como pista puedo decir que utilizando la versión de evaluación del XAMLSpy 
    (que por cierto está muy bien) he visto que en ningún momento el DataContext
    desparece, ni cambia. Simplemente no le llega el valor, es como si no evaluara
    el Binding (he probado a hacer el binding programaticamente y tampoco he sido 
    capaz de que funcione correctamente).

    No sé el que, pero hay algo que no estoy haciendo bien.                                       

    viernes, 21 de septiembre de 2012 14:12
  • Inténtalo con esto, a ver:

    private static void OnUserControlTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ucPrueba miControl = d as ucPrueba;
        d.UserControlText = e.NewValue;
    }





    • Editado aZubi viernes, 21 de septiembre de 2012 14:24
    viernes, 21 de septiembre de 2012 14:24
  • Nada, ya lo intenté con esto (no lo puse antes por no meter más ruido). Lo ví en un blog de un francés del que no entendía casi nada y lo puse por si acaso, aunque no le veo mucha lógica

                ucPrueba uc = (ucPrueba)d;
                uc.tbFrecuencia.Text = (string)e.NewValue;
    

    viernes, 21 de septiembre de 2012 15:02
  • Justo hoy he tenido un problema similar con un custom control. No sé si la solución valdrá para el UserControl, pero poniéndolo de esta forma me ha funcionado:

    <TextBox x:Name="tbFrecuencia" TextWrapping="Wrap" Margin="0" VerticalAlignment="Top" d:LayoutOverrides="VerticalAlignment" Text="{Binding UserControlText, RelativeSource={RelativeSource TemplatedParent}}"/>

    La verdad es que no sé porqué.

    viernes, 21 de septiembre de 2012 15:54
  • Muchas gracias aZubi,

    Hoy no lo voy a poder probar, pero en cuanto lo pruebo te cuento.

    viernes, 21 de septiembre de 2012 21:01
  • Nada, tampoco ha funcionado. Es increíble si le paso un string no hay problema, funciona como debería funcionar. 

    <ViewControles:ucPrueba x:Name="tbPrueba" Width="150" Margin="0" UserControlText="rabano" ></ViewControles:ucPrueba>

    pero si le paso un binding no hace nada, es como si no se le hubiera puesto nada

    <ViewControles:ucPrueba x:Name="tbPrueba" Width="150" Margin="0" UserControlText="{Binding NewPlanificacion.Prueba, Mode=TwoWay}"  ></ViewControles:ucPrueba>


    En fin que creo que lo voy a resolver por la cuenta de la vieja con CodeBehind y santas pascuas. Ya llevo cuatro días perdidos con este asunto. Algún día aprenderé a hacerlo bien ....

    Gracias de todas manera,

    aunque si alguien sabe cual puede ser la solución se lo agradecería infinito o si me pudiera mandar un ejemplo de un user control que funcione con una Dependency Property y con DataBinding pues lo mismo.

    Gracias aZubi por tus esfuerzos

    sábado, 22 de septiembre de 2012 10:33
  • Hola MartinRomania,

    He creado un proiecto con tu código y he estado trasteando un poquito. Al final he conseguido que funcione. Pego a continuación el código C# y XAML de tu user control:

    public partial class ucPrueba : UserControl
        {
            public ucPrueba()
            {
                InitializeComponent();
            }
    
            public static readonly DependencyProperty UserControlTextProperty = DependencyProperty.Register("UserControlText", typeof(string), typeof(ucPrueba), null);
    
            public string UserControlText
            {
                get { return (string)GetValue(UserControlTextProperty); }
                set
                { SetValue(UserControlTextProperty, value); }
            }
        }


    <UserControl x:Class="PhoneApp2.ucPrueba" Name="myucPrueba"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        d:DesignHeight="480" d:DesignWidth="480" Height="74">
    
    
        <Grid x:Name="LayoutRoot" Margin="0">
            <TextBox x:Name="tbFrecuencia" TextWrapping="Wrap" Margin="0" VerticalAlignment="Top" d:LayoutOverrides="VerticalAlignment" Text="{Binding UserControlText, ElementName=myucPrueba}" />
        </Grid>
    </UserControl>


    He puesto en negrita los cambios más significativos. Como podrás observar lo que cambia es el binding a la propiedad Text del TextBox de tu UserControl. Parece ser que este binding no se hacia correctamente anteriormente, porque no cogía bien el DataContext. Poniendolo de esta forma funciona bien.

    Espero que te sirva de ayuda.


    • Editado aZubi sábado, 22 de septiembre de 2012 14:01
    • Propuesto como respuesta MartinRomania sábado, 22 de septiembre de 2012 22:29
    • Marcado como respuesta Bazookao miércoles, 26 de septiembre de 2012 16:45
    sábado, 22 de septiembre de 2012 13:56
  • Gracias aZubi. 

    Ahora si me funciona, muchas gracias

    sábado, 22 de septiembre de 2012 22:41