Binding Silverlight UserControl custom properties to its' elements

后端 未结 6 596
长情又很酷
长情又很酷 2021-02-05 09:59

I\'m trying to make a simple crossword puzzle game in Silverlight 2.0. I\'m working on a UserControl-ish component that represents a square in the puzzle. I\'m having trouble wi

相关标签:
6条回答
  • 2021-02-05 10:40

    First, set the DataContext on the UserControl using {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}}">
    

    Now you can bind the individual elements to the properties of the usercontrol:

    <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" />
    

    For SL 2.0, you'll need to set the DataContext on the UserControl's Loaded event handler.

    private void UserControl_Loaded( object sender, RoutedEventArgs e ) {
        LayoutRoot.DataContext = this;
    }
    
    0 讨论(0)
  • 2021-02-05 10:43

    As Silverlight cannot use FindAncestor technique you can use a trick similar to the one that sets the UserControl's name, but without breaking its functionality by using the name of the 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>
    

    It worked in SL3 without having to add any additional code (I'm using it in a WP7 app), but don't know if you can use it in SL2. Well, I realize now how this question is old, hope it's still helpful, I've arrived here because the answers I got for the same problem in WP7 didn't convince me.

    0 讨论(0)
  • 2021-02-05 10:45

    I may not be understanding your issue exactly. In Silverlight, you are able to bind to almost any data object. So, if you have a PuzzleSquare class that contains properties Content and Label, you may bind to these properties directly from the object.

    Let's say you created a simple object 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;
          }    
        }
    

    So, if you are building the app with the classic view/code behind model, your code behind would add this object to the DataContext property of the grid on page load:

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

    Your Xaml would bind to the Square property:

        <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" />
    

    Does that make sense?

    ib.

    0 讨论(0)
  • 2021-02-05 10:56

    Try this:

    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
    

    I can bind in both XAML and code behind.

    0 讨论(0)
  • 2021-02-05 11:00

    This worked in Silverlight 4.0

    Put a name on the UserControl, and then refer to it in the TextBlock

     <UserControl x:Class="XWord.Square"
        ...omitted for brevity ...
        x:Name="Square">
    
            <TextBlock x:Name="Label" ...
                Text="{Binding Path=LabelText,ElementName=Square}"/>
    
    0 讨论(0)
  • 2021-02-05 11:01

    I think you are looking for UI Element to Element Binding which is a feature of Silverlight 3.

    0 讨论(0)
提交回复
热议问题