silverlight data-binding user-controls silverlight-2.0

Vincular las propiedades personalizadas de Silverlight UserControl a sus elementos



data-binding user-controls (6)

Como Silverlight no puede usar la técnica FindAncestor, puede usar un truco similar al que establece el nombre del UserControl, pero sin romper su funcionalidad usando el nombre del LayoutRoot ...

<UserControl x:Class="XWord.Square" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FontSize="30" Width="100" Height="100"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock x:Name="{Binding Path=Parent.LabelText, ElementName=LayoutRoot}" Grid.Row="0" Grid.Column="1" Text="7"/> <TextBox x:Name="{Binding Path=Parent.ContentCharacter, ElementName=LayoutRoot}" Grid.Row="1" Grid.Column="0" Text="A" BorderThickness="0" /> </Grid> </UserControl>

Funcionó en SL3 sin tener que agregar ningún código adicional (lo estoy usando en una aplicación WP7), pero no sé si puede usarlo en SL2. Bueno, ahora me doy cuenta de que esta pregunta es antigua, espero que siga siendo útil. Llegué aquí porque las respuestas que obtuve para el mismo problema en WP7 no me convencieron.

Estoy tratando de hacer un simple juego de crucigramas en Silverlight 2.0. Estoy trabajando en un componente UserControl-ish que representa un cuadrado en el rompecabezas. Tengo problemas para vincular las propiedades de mi UserControl con sus elementos. Finalmente, (de alguna manera) lo puse en funcionamiento (puede ser útil para algunos, me tomó varias horas), pero quería hacerlo más "elegante".

Me he imaginado que debería tener un compartimento para el contenido y una etiqueta (en la esquina superior derecha) que opcionalmente contiene su número. El control de contenido probablemente sea un TextBox, mientras que el control de etiquetas podría ser un TextBlock. Así que creé un UserControl con esta estructura básica (los valores están codificados en esta etapa):

<UserControl x:Class="XWord.Square" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FontSize="30" Width="100" Height="100"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock x:Name="Label" Grid.Row="0" Grid.Column="1" Text="7"/> <TextBox x:Name="Content" Grid.Row="1" Grid.Column="0" Text="A" BorderThickness="0" /> </Grid> </UserControl>

También he creado DependencyProperties en la clase Square como esta:

public static readonly DependencyProperty LabelTextProperty; public static readonly DependencyProperty ContentCharacterProperty; // ...(static constructor with property registration, .NET properties // omitted for brevity)...

Ahora me gustaría averiguar cómo vincular el elemento Etiqueta y Contenido a las dos propiedades. Lo hago así (en el archivo de código subyacente):

Label.SetBinding( TextBlock.TextProperty, new Binding { Source = this, Path = new PropertyPath( "LabelText" ), Mode = BindingMode.OneWay } ); Content.SetBinding( TextBox.TextProperty, new Binding { Source = this, Path = new PropertyPath( "ContentCharacter" ), Mode = BindingMode.TwoWay } );

Eso sería más elegante hecho en XAML. ¿Alguien sabe cómo se hace?



Esto funcionó en Silverlight 4.0.

Ponga un nombre en UserControl y luego refiéralo en el TextBlock

<UserControl x:Class="XWord.Square" ...omitted for brevity ... x:Name="Square"> <TextBlock x:Name="Label" ... Text="{Binding Path=LabelText,ElementName=Square}"/>


Primero, configure el DataContext en el UserControl usando {RelativeSource Self}:

<UserControl x:Class="XWord.Square" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FontSize="30" Width="100" Height="100" DataContext="{Binding RelativeSource={RelativeSource Self}}">

Ahora puede vincular los elementos individuales a las propiedades del control de usuario:

<TextBlock x:Name="Label" Grid.Row="0" Grid.Column="1" Text="{Binding LabelText}"/> <TextBox x:Name="Content" Grid.Row="1" Grid.Column="0" Text="{Binding ContentCharacter}" BorderThickness="0" />

Para SL 2.0, deberá configurar el DataContext en el controlador de eventos Loaded del UserControl.

private void UserControl_Loaded( object sender, RoutedEventArgs e ) { LayoutRoot.DataContext = this; }


Prueba esto:

Public ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(ButtonEdit), New System.Windows.PropertyMetadata("", AddressOf TextPropertyChanged)) Public Property Text As String Get Return GetValue(TextProperty) End Get Set(ByVal value As String) SetValue(TextProperty, value) End Set End Property Private Sub TextPropertyChanged() If String.IsNullOrEmpty(Text) Then TextBox1.Text = "" Else TextBox1.Text = Text End If End Sub Private Sub TextBox1_LostFocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles TextBox1.LostFocus Text = TextBox1.Text End Sub

Puedo enlazar tanto XAML como el código detrás.


Puede que no esté entendiendo su problema exactamente. En Silverlight, puede enlazar a casi cualquier objeto de datos. Por lo tanto, si tiene una clase de PuzzleSquare que contiene las propiedades Contenido y Etiqueta, puede enlazarlas directamente desde el objeto.

Digamos que creaste un objeto simple PuzzleSquare:

public class PuzzleSquare { public string Content{ get; set; } public string Label{ get; set; } public void PuzzleSquare(){}; public void PuzzleSquare(string label, string content):this() { Content = content; Label = label; } }

Por lo tanto, si está creando la aplicación con la vista / código clásico detrás del modelo, su código detrás agregará este objeto a la propiedad DataContext de la cuadrícula en la carga de la página:

LayoutRoot.DataContext = new PuzzleSquare("1", "A");

Tu Xaml se uniría a la propiedad Cuadrado:

<TextBlock x:Name="Label" Grid.Row="0" Grid.Column="1" Text="{Binding Label}"/> <TextBox x:Name="Content" Grid.Row="1" Grid.Column="0" Text="{Binding Content}" BorderThickness="0" />

¿Tiene sentido?

ib.