将UserControl属性绑定到Window属性

时间:2014-02-19 11:11:12

标签: c# wpf binding

我正在努力解决一些具有约束力的问题。 我有一个带TextBlock的UserControl。 TextBlock的文本绑定到属性。 在窗口中使用UserControl并使用某些文本设置属性时,一切都按预期工作。但是当我将该属性绑定到窗口中的另一个属性时,没有任何反应。 这是一个显示问题的示例:

UserControl xaml:

<UserControl x:Class="TestBinding.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<TextBlock Text="{Binding SomeText}"/>

UserControl代码:

public partial class UserControl1 : UserControl
{
    public static readonly DependencyProperty SomeTextProperty = DependencyProperty.Register("SomeText", typeof(string), typeof(UserControl1), new PropertyMetadata("Control Default Text"));

    public string SomeText
    {
        get { return (string)this.GetValue(SomeTextProperty); }
        set { this.SetValue(SomeTextProperty, value); }
    }

    public UserControl1()
    {
        this.DataContext = this;

        InitializeComponent();
    }
}

Window xaml:

<Window x:Class="TestBinding.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestBinding"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>
    <local:UserControl1 Grid.Row="0" Grid.Column="0"/>
    <local:UserControl1 Grid.Row="1" Grid.Column="0" SomeText="Another Text" />
    <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding SomeText}"/>
    <local:UserControl1 Grid.Row="1" Grid.Column="1" SomeText="{Binding SomeText}" />
</Grid>

窗口代码:

public partial class MainWindow : Window
{
    public static readonly DependencyProperty SomeTextProperty = DependencyProperty.Register("SomeText", typeof(string), typeof(MainWindow), new PropertyMetadata("Window Default Text"));

    public string SomeText
    {
        get { return (string)this.GetValue(SomeTextProperty); }
        set { this.SetValue(SomeTextProperty, value); }
    }

    public MainWindow()
    {
        this.DataContext = this;

        InitializeComponent();
    }
}

我希望在右下角看到的是“窗口默认文本”,但我得到的是“控制默认文本”。

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

您已在UserControl构造函数中将DataContext显式设置为自身。

public UserControl1()
{
    this.DataContext = this;  <-- HERE

    InitializeComponent();
}

默认情况下, 绑定引擎将搜索其DataContext 中的所有属性,即在其自身内。因此,找不到MainWindow.SomeText属性。

你必须像这样明确地解决它:

<local:UserControl1 Grid.Row="1" Grid.Column="1"
                    SomeText="{Binding DataContext.SomeText,
                               RelativeSource={RelativeSource Mode=FindAncestor, 
                                                        AncestorType=Window}}" />

不要在UserControl构造函数中将DataContext设置为自身,并将UserControl中TextBlock的绑定更改为:

<TextBlock Text="{Binding SomeText,
               RelativeSource={RelativeSource Mode=FindAncestor, 
                                    AncestorType=UserControl}}"/>

这样它会自动继承windows dataContext。

答案 1 :(得分:0)

当您将UserControl1.SomeText设置为文本时,它会起作用,因为绑定上下文无关紧要,但是当您使用绑定并执行

public UserControl1()
{
    this.DataContext = this;
    ....
}

通过继承和更改DataContext绑定的上下文来覆盖通常存在的UserControl1。删除上面的行并更改XAML,如下所示:

<UserControl ... x:Name="myUserControl">
    <TextBlock Text="{Binding ElementName=myUserControl, Path=SomeText}"/>