问题描述
<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 的所有代码.
The above code shows my WatermarkTextBox
control. In the code behind file I have set the DataContext
. I left out all the code for the DP's of the control.
public WatermarkTextBox()
{
InitializeComponent();
grid.DataContext = this;
}
我必须将 DataContext
绑定到网格,否则水印和实际文本的 Text
属性都不会显示.现在的问题是我无法在 Grid
之外设置 Border
的 Background
.
I had to bind the DataContext
to the grid because otherwise the Text
properties of both the watermark and actual text wouldn't display. The problem now is that I can't set the Background
of the Border
outside of the Grid
.
我尝试了下面的代码,但只设置了 Border
的 Background
而不是水印和实际文本.
I tried the code below but then only the Background
of the Border
is set and not the watermark and actual text.
public WatermarkTextBox()
{
InitializeComponent();
this.DataContext = this;
grid.DataContext = this;
}
推荐答案
在像这样的 UserControl 中,你永远不应该明确地将 DataContext 设置为 this
或其他任何东西,因为 DataContext 通常在外部设置时您在应用程序的某处使用 UserControl.外部应用的 DataContext 通常是应用程序的视图模型(的一部分).
In a UserControl like this you should never exlicitly set the DataContext to this
or anyting else, because the DataContext is usually set externally when you use the UserControl somewhere in your application. The externally applied DataContext is typically (part of) the application's view model.
您应该改为更改内部绑定,以便它们使用显式RelativeSource
:
You should instead change your internal bindings so that they use an explicit 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 分配.
and then remove any DataContext assignment from the UserControl's constructor.
参见例如这个答案(以及许多其他类似的)详细讨论了这个话题.
See e.g. this answer (and many other similar) that discuss this topic in detail.
这篇关于数据上下文冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!