我用
创建了一个虚拟窗口两个按钮都以蓝色开始,当选中该复选框时,它们都应该变为橙色。但是,用户控件中的一个似乎忽略了复选框。 为什么会失败,我该如何解决这个问题?
我要插入的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>
主窗口:
<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>
答案 0 :(得分:1)
为什么失败
因为UserControl中没有名为“myCheckBox”的CheckBox。父窗口中的CheckBox位于另一个命名范围内,因此绑定到ElementName将不起作用。
我怎样才能解决这个问题?
学习并实施MVVM设计模式:https://msdn.microsoft.com/en-us/library/hh848246.aspx。在开发基于XAML的UI应用程序时,它是 推荐的设计模式。
创建保存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设置为此实例并绑定到其IsChecked属性,而不是直接绑定到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属性:
<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>
答案 1 :(得分:0)
您无法从样式中引用myCheckBox,这是两个不同的范围。此外,该样式的目标是一个按钮,但该控件是一个Window。您必须将样式中的所有控件放在控件模板中。