将 Silverlight UserControl 自定义属性绑定到其元素自定义、绑定、属性、元素

2023-09-07 15:42:19 作者:假如能重来

我正在尝试在 Silverlight 2.0 中制作一个简单的填字游戏.我正在开发一个 UserControl-ish 组件,它代表拼图中的一个正方形.我在将 UserControl 的属性与其元素绑定时遇到问题.我终于(有点)让它工作了(可能对某些人有帮助——我花了好几个小时),但想让它更优雅".

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 with binding up my UserControl's properties with its' elements. I've finally (sort of) got it working (may be helpful to some - it took me a few long hours), but wanted to make it more 'elegant'.

我想象它应该有一个内容隔间和一个标签(在右上角),可以选择包含其编号.内容控件可能是 TextBox,而标签控件可能是 TextBlock.所以我用这个基本结构创建了一个 UserControl(值在这个阶段是硬编码的):

I've imagined it should have a compartment for the content and a label (in the upper right corner) that optionally contains its' number. The content control probably be a TextBox, while label control could be a TextBlock. So I created a UserControl with this basic structure (the values are hardcoded at this stage):

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

我还在 Square 类中创建了 DependencyProperties,如下所示:

I've also created DependencyProperties in the Square class like this:

     public static readonly DependencyProperty LabelTextProperty;
     public static readonly DependencyProperty ContentCharacterProperty;

     // ...(static constructor with property registration, .NET properties
     // omitted for brevity)...

现在我想弄清楚如何将 Label 和 Content 元素绑定到这两个属性.我这样做(在代码隐藏文件中):

Now I'd like to figure out how to bind the Label and Content element to the two properties. I do it like this (in the code-behind file):

     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 } );

在 XAML 中这样做会更优雅.有谁知道这是怎么做到的?

That would be more elegant done in XAML. Does anyone know how that's done?

推荐答案

首先,使用 {RelativeSource Self} 在 UserControl 上设置 DataContext:

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

对于 SL 2.0,您需要在 UserControl 的 Loaded 事件处理程序上设置 DataContext.

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;
}