Datacontext conflicts

混江龙づ霸主 提交于 2019-11-26 12:33:52

问题


<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>

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;
}

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.

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;
}

回答1:


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.

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}}" />

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.



来源:https://stackoverflow.com/questions/25699218/datacontext-conflicts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!