<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
答案 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(和许多其他类似的)详细讨论这个主题。