C# {Binding elementName…}失败

C# {Binding elementName…}失败,c#,wpf,xaml,scope,C#,Wpf,Xaml,Scope,我已经创建了一个虚拟窗口 复选框 钮扣 自定义用户控件中的按钮 两个按钮都以蓝色开头,当选中复选框时,它们都应变为橙色。但是,用户控件中的控件似乎忽略了复选框为什么会失败,我该如何解决这个问题? 要插入的UserControl: <UserControl x:Class="UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http:

我已经创建了一个虚拟窗口

  • 复选框
  • 钮扣
  • 自定义用户控件中的按钮
两个按钮都以蓝色开头,当选中复选框时,它们都应变为橙色。但是,用户控件中的控件似乎忽略了复选框为什么会失败,我该如何解决这个问题?

要插入的UserControl:

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

您不能从样式中引用myCheckBox,这是两个不同的范围。另外,样式的目标是一个按钮,但控件是一个窗口。您必须将所有控件放在控件模板的样式中

为什么它失败了

因为UserControl中没有名为“myCheckBox”的复选框。父窗口中的复选框位于另一个命名范围中,因此绑定到ElementName在此处不起作用

我怎样才能避开这件事

学习并实现MVVM设计模式:。在开发基于XAML的UI应用程序时,建议使用这种设计模式

创建保存复选框当前状态的视图模型类:

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));
    }
}
<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>
并将窗口的DataContext设置为此实例,并绑定到其IsChecked属性,而不是直接绑定到复选框:

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));
    }
}
<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属性:

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


无法保证;但我有一种强烈的感觉,
myCheckbox
一旦进入
UserControl1
就超出了范围。我猜你有一个系统。数据例外。对此您无能为力,但不要太依赖elementName,请记住投票选出有用的答案:)