DataContext的冲突 [英] Datacontext conflicts

查看:142
本文介绍了DataContext的冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 <用户控件X:类=WatermarkTextBox
             的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
             的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
             的xmlns:D =htt​​p://schemas.microsoft.com/ex$p$pssion/blend/2008
             的xmlns:MC =htt​​p://schemas.openxmlformats.org/markup-compatibility/2006
             MC:可忽略=D
             D:DesignHeight =30
             D:DesignWidth =250>
    < UserControl.Resources>
        < BooleanToVisibilityConverter X:键=BooleanToVisibilityConverter/>
    < /UserControl.Resources>
    < BORDER>
        <电网X:名称=网格>
            < TextBlock的文本={结合水印,FallbackValue =此提示dissappears在键入...}
                       能见度={绑定的ElementName = txtUserEntry,路径= Text.IsEmpty,转换器= {StaticResource的BooleanToVisibilityConverter}}/>
            <文本框名称=txtUserEntry
                     文本={结合文字,UpdateSourceTrigger =的PropertyChanged}/>
        < /网格和GT;
    < /边框>
< /用户控件>

以上code显示了我的 WatermarkTextBox 控制。在隐藏文件code我已经设置了的DataContext 。我离开了所有的code为DP的控制的。

 公共WatermarkTextBox()
{
    的InitializeComponent();
    grid.DataContext =这一点;
}

我不得不在的DataContext 绑定到网格,因为水印和实际文本两者否则文本属性将不显示。现在的问题是,我不能设置背景边框之外

我试过低于code,但那么只有背景的设置,而不是边框的水印和实际文本。

 公共WatermarkTextBox()
{
    的InitializeComponent();
    this.DataContext =这一点;
    grid.DataContext =这一点;
}


解决方案

在这样的你可千万别exlicitly设置的DataContext一个用户控件到这个或点儿别的,因为DataContext的通常设置在外部,当你在应用程序中的某个地方使用的用户控件。外部施加的DataContext通常(部分)应用程序的视图模式。

,以便他们使用而应该修改内部绑定一个明确的的RelativeSource

 <的TextBlock
    文本={绑定路径=水印,
                   的RelativeSource = {的RelativeSource AncestorType =用户控件},
                   FallbackValue =此提示dissappears在键入...}
    能见度={绑定的ElementName = txtUserEntry,
                         路径= Text.IsEmpty,
                         转换器= {StaticResource的BooleanToVisibilityConverter}}/>
<文本框
    NAME =txtUserEntry
    文本={绑定路径=文字,
                   UpdateSourceTrigger = PropertyChanged的,
                   的RelativeSource = {的RelativeSource AncestorType =用户控件}}/>

,然后从用户控件的构造函数中的任何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>

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

解决方案

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.

这篇关于DataContext的冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆