Datacontext冲突

时间:2014-09-06 10:16:48

标签: wpf binding datacontext

<UserControl x:Class="WatermarkTextBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             d:DesignHeight="30"
             d:DesignWidth="250">
    <UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    </UserControl.Resources>
    <Border>
        <Grid x:Name="grid">
            <TextBlock Text="{Binding Watermark, FallbackValue=This prompt dissappears as you type...}"
                       Visibility="{Binding ElementName=txtUserEntry, Path=Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}}" />
            <TextBox Name="txtUserEntry"
                     Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" />
        </Grid>
    </Border>
</UserControl>

上面的代码显示了我的WatermarkTextBox控件。在代码隐藏文件中,我设置了DataContext。我省略了DP控制器的所有代码。

public WatermarkTextBox()
{
    InitializeComponent();
    grid.DataContext = this;
}

我必须将DataContext绑定到网格,否则水印和实际文本的Text属性都不会显示。现在的问题是,我无法在Background之外设置Border的{​​{1}}。

我尝试了下面的代码,但只设置了Grid的{​​{1}},而不是水印和实际文字。

Background

1 个答案:

答案 0 :(得分:3)

在像这样的UserControl中,你永远不应该将DataContext明确地设置为this或其他任何东西,因为当你在应用程序的某个地方使用UserControl时,通常会在外部设置DataContext。外部应用的DataContext通常是应用程序视图模型的一部分。

您应该更改内部绑定,以便他们使用明确的RelativeSource

<TextBlock
    Text="{Binding Path=Watermark,
                   RelativeSource={RelativeSource AncestorType=UserControl},
                   FallbackValue=This prompt dissappears as you type...}"
    Visibility="{Binding ElementName=txtUserEntry,
                         Path=Text.IsEmpty,
                         Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBox
    Name="txtUserEntry"
    Text="{Binding Path=Text,
                   UpdateSourceTrigger=PropertyChanged,
                   RelativeSource={RelativeSource AncestorType=UserControl}}" />

然后从UserControl的构造函数中删除任何DataContext赋值。

参见例如this answer(和许多其他类似的)详细讨论这个主题。