{Binding elementName...} 失败 [英] {Binding elementName...} failing

查看:57
本文介绍了{Binding elementName...} 失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用

  • 一个复选框
  • 一个按钮
  • 自定义用户控件中的按钮

两个按钮都以蓝色开始,选中复选框后,它们都应变为橙色.但是,用户控件内的那个似乎忽略了复选框.为什么会失败,我该如何解决?

Both Buttons start out Blue, and when the checkbox is checked, they should both turn orange. However, the one inside the user control seems to be ignoring the checkbox. Why is it failing, and how can I get around this?

我想插入的用户控件:

<UserControl x:Class="UserControl1"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       mc:Ignorable="d"
       d:DesignHeight="300" d:DesignWidth="300"
       DataContext="{Binding RelativeSource={RelativeSource Self}}"


       <Grid>
            <!--MyContent is a dependency property in UserControl1's code behind-->
            <ContentControl Content="{Binding MyContent}">      
       </Grid>
</UserControl>

主窗口:

<Window x:Class="WpfApplication11.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title="MainWindow" Height="350" Width="525">
       <Window.Resources>
           <ResourceDictionary>

               <Style TargetType="Button">
                   <Setter Property="Background" Value="Cyan"/>
                   <Style.Triggers>
                       <DataTrigger Binding="{Binding ElementName=myCheckbox, Path=isChecked}" Value="True">
                           <Setter Property="Background" Value="Orange/>
                       </DataTrigger>
                   </Style.Triggers>
               </Style>

               <Button x:Key="Button1"  Content="Button1"/>
               <Button x:Key="Button2"  Content="Button2"/>

           </ResourceDictionary>
       </Window.Resources>

       <Grid>
           <Grid.RowDefinitions>
               <RowDefinition Height="1*"/>
               <RowDefinition Height="1*"/>
               <RowDefinition Height="1*"/>
           </Grid.RowDefinitions>

           <CheckBox x:Name = "myCheckBox" Content="Turn Orange" Grid.Row="0"/>

           <!--This updates when I check myCheckBox-->        
           <ContentControl Content = "{StaticResource Button1}" Grid.Row="2"/>

           <!--This does NOT update when I check myCheckBox-->
           <test:UserControl1 MyContent="{StaticResource Button2}" Grid.Row="2"/>

       </Grid>
</Window>

推荐答案

为什么会失败

因为 UserControl 中没有名为myCheckBox"的 CheckBox.父窗口中的 CheckBox 驻留在另一个命名范围内,因此此处无法绑定到 ElementName.

Because there is no CheckBox named "myCheckBox" in the UserControl. The CheckBox in the parent window resides in another naming scope so binding to an ElementName won't work here.

我该如何解决这个问题?

How can I get around this?

学习和实现 MVVM 设计模式:https://msdn.microsoft.com/en-us/library/hh848246.aspx.这是在开发基于 XAML 的 UI 应用程序时推荐使用的设计模式.

Learn and implement MVVM design pattern: https://msdn.microsoft.com/en-us/library/hh848246.aspx. It is the recommended design pattern to use when developing XAML based UI applications.

创建保存 CheckBox 当前状态的视图模型类:

Create view model class that holds the current status of the CheckBox:

public class ViewModel : INotifyPropertyChanged
{
    private bool _isChecked;
    public bool IsChecked
    {
        get { return _isChecked; }
        set { _isChecked = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

并将窗口的 DataContext 设置为 this 的一个实例并绑定到它的 IsChecked 属性,而不是直接绑定到 CheckBox:

And set the DataContext of the window to an instance of this and bind to its IsChecked property instead of binding directly to the CheckBox:

<Window ...>
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Cyan"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsChecked}" Value="True">
                    <Setter Property="Background" Value="Orange"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
        <Button x:Key="Button1"  Content="Button1"/>
        <Button x:Key="Button2"  Content="Button2"/>
    </Window.Resources>
    <Window.DataContext>
        <test:ViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>

        <CheckBox x:Name ="myCheckBox" Content="Turn Orange" Grid.Row="0" IsChecked="{Binding IsChecked}"/>

        <ContentControl Content = "{StaticResource Button1}" Grid.Row="1"/>

        <test:UserControl2 MyContent="{StaticResource Button2}" Grid.Row="2"/>

    </Grid>
</Window>

UserControl 应该继承父窗口的 DataContext,所以不要在 UserControl1.xaml 中显式设置 DataContext 属性:

The UserControl should inherit the DataContext of the parent window so don't set the DataContext property explicitly in UserControl1.xaml:

<UserControl x:Class="WpfApplication11.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApplication2"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <ContentControl Content="{Binding MyContent, RelativeSource={RelativeSource AncestorType=UserControl}}" />
    </Grid>
</UserControl>

这篇关于{Binding elementName...} 失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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