【问题标题】:How to make a Binding when DataContext is already set已设置 DataContext 时如何进行绑定
【发布时间】:2014-10-07 14:20:19
【问题描述】:

我有一个自定义的UserControl,我将DataContext 设置为某个对象的绑定。我还想根据绑定到父对象中的布尔值来启用或禁用控件。然而,这失败了,因为一旦设置了数据上下文,系统就会尝试在新数据上下文中查找所有其他绑定而不是旧数据上下文。 (无论如何,这对我来说似乎有点奇怪。)

public class Animal
{
    public string Name;
}

public class Zoo
{
    public Zoo ()
    {
        AnimalOnDisplay = new AnimalOnDisplay { Name = "Tyrannosaurus" };
    }

     public bool ZooIsClosed;
     public Animal AnimalOnDisplay;
}

static void Main()
{
    ZooUserControl control = new ZooUserControl ();
    control.DataContext = new Zoo();
    control.Show();
}

XAML:

<UserControl x:Class="MyProgramme.ZooUserControl"
             xmlns:zoo="clr-namespace:Zoo.UserControls">
    <StackPanel>

        <Label Content="Welcome!" />
        <zoo:AnimalUserControl DataContext="{Binding AnimalOnDisplay}"
                               IsEnabled="{Binding ZooIsClosed}" />

    </StackPanel>
</UserControl>

上述用户控件的DataContextZoo 的有效实例(我检查了这个)。这会产生以下错误:

 System.Windows.Data Error: 40 : BindingExpression path error: 'ZooIsClosed' property not found on 'object' ''Animal`1' (HashCode=44290843)'. 
                                 BindingExpression:Path=ZooIsClosed; DataItem='Animal`1' (HashCode=44290843); target element is 'AnimalUserControl' (Name=''); 
                                 target property is 'IsEnabled' (type 'Boolean')

很明显,它在错误的地方寻找ZooIsClosed。我尝试将它绑定到当前的DataContext,如下所示:

 IsEnabled="{Binding ZooIsClosed, RelativeSource={RelativeSource Self}}"

这会产生同样的错误,并带有 ElementName,这也不起作用。

如何将它绑定到正确的变量(即Zoo 中的ZooIsClosed)?

【问题讨论】:

    标签: c# wpf binding datacontext


    【解决方案1】:

    您可以使用RelativeSource 跟踪UserControlIsEnabled 设置Binding,如下所示:

    <zoo:AnimalUserControl DataContext="{Binding AnimalOnDisplay}"
             IsEnabled="{Binding DataContext.ZooIsClosed,
                        RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    

    注意Path 设置为DataContext.ZooIsClosed

    您的模型也没有正确编写(我希望它只是说明性的)。

    【讨论】:

    • 是的,这行得通,谢谢! (我知道,该模型是示范性的,未经测试,无疑包含错误,抱歉。)
    【解决方案2】:

    您所做的是要求绑定在您的 AnimalOnDisplay 属性上搜索名为 ZooIsClosed 的属性。从你后面的代码我们可以看出,这种关系是不存在的。

    因为ZooIsClosedAnimalOnDisplay 都是Zoo 类的属性,所以你应该将DataContext 设置为Zoo 类实例(假设你的ZooControl 有一个Zoo 实例DependencyProperty),然后绑定到该实例上的属性,即IsZooClosedAnimalOnDisplay

    这里有一些代码可以帮助您入门,看看它是否符合您的需求:

    <UserControl x:Class="MyProgramme.ZooUserControl"
             xmlns:zoo="clr-namespace:Zoo.UserControls"
             DataContext="{Binding Zoo.DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type zoo:ZooControl}}}">
        <StackPanel>
            <Label Content="Welcome!" />
            <zoo:AnimalUserControl IsEnabled="{Binding ZooIsClosed}" />
        </StackPanel>
    </UserControl>
    

    【讨论】:

    • 你说得对,我的问题不清楚/不完整。我对其进行了编辑:用户控件的DataContextZoo 类的有效实例。现在问题更清楚了:AnimalUserControl 需要不同的DataContext,但IsEnabled 仍应绑定到当前的。
    猜你喜欢
    • 1970-01-01
    • 2021-09-05
    • 2010-09-27
    • 2013-02-19
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 2012-12-26
    相关资源
    最近更新 更多