Ron*_*īts 17 data-binding silverlight user-controls silverlight-2.0
我正在尝试在Silverlight 2.0中制作一个简单的填字游戏.我正在研究一个UserControl-ish组件,它代表了拼图中的一个正方形.我将UserControl的属性与其元素绑定在一起时遇到了麻烦.我终于(有点)让它工作了(可能对某些人有所帮助 - 它花了我几个小时),但是想让它更"优雅".
我想象它应该有内容的隔间和标签(在右上角),可选地包含它的'数字.内容控件可能是TextBox,而标签控件可能是TextBlock.所以我用这个基本结构创建了一个UserControl(这个值在这个阶段是硬编码的):
<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>
Run Code Online (Sandbox Code Playgroud)
我也在Square类中创建了DependencyProperties,如下所示:
public static readonly DependencyProperty LabelTextProperty;
public static readonly DependencyProperty ContentCharacterProperty;
// ...(static constructor with property registration, .NET properties
// omitted for brevity)...
Run Code Online (Sandbox Code Playgroud)
现在我想弄清楚如何将Label和Content元素绑定到两个属性.我是这样做的(在代码隐藏文件中):
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 } );
Run Code Online (Sandbox Code Playgroud)
这在XAML中会更优雅.有谁知道这是怎么做的?
lo5*_*lo5 19
首先,使用{RelativeSource Self}在UserControl上设置DataContext:
<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}}">
Run Code Online (Sandbox Code Playgroud)
现在,您可以将各个元素绑定到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" />
Run Code Online (Sandbox Code Playgroud)
对于SL 2.0,您需要在UserControl的Loaded事件处理程序上设置DataContext.
private void UserControl_Loaded( object sender, RoutedEventArgs e ) {
LayoutRoot.DataContext = this;
}
Run Code Online (Sandbox Code Playgroud)
由于Silverlight无法使用FindAncestor技术,您可以使用类似于设置UserControl名称的技巧,但不会通过使用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>
Run Code Online (Sandbox Code Playgroud)
它在SL3中工作,无需添加任何额外的代码(我在WP7应用程序中使用它),但不知道你是否可以在SL2中使用它.好吧,我现在意识到这个问题是如何陈旧的,希望它仍然有用,我来到这里是因为我在WP7中遇到同样问题的答案并没有让我信服.
小智 1
我可能不太清楚你的问题。在 Silverlight 中,您可以绑定到几乎任何数据对象。因此,如果您有一个包含 Content 和 Label 属性的 PuzzleSquare 类,您可以直接从对象绑定到这些属性。
假设您创建了一个简单的对象 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;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果您使用经典视图/隐藏代码模型构建应用程序,则隐藏代码会在页面加载时将此对象添加到网格的 DataContext 属性中:
LayoutRoot.DataContext = new PuzzleSquare("1", "A");
Run Code Online (Sandbox Code Playgroud)
您的 Xaml 将绑定到 Square 属性:
<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" />
Run Code Online (Sandbox Code Playgroud)
那有意义吗?
ib.