在自定义的TemplatedControl中,我有一个ItemsControl,它在自定义的TemplatedControl之外填充。我希望ItemsControl的(未来)子项自动从ItemsControl继承Foreground值。
我希望能够从TemplatedControl更改Foreground值,并让子控件也更新它们的Foreground。
这是我拥有的ItemsControl:
<ItemsControl x:Name="PrimaryItems" ItemsSource="{TemplateBinding PrimaryItems}" Foreground="{TemplateBinding MyCustomForeground}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
当我使用TemplatedControl时,它看起来像这样:
<Grid>
<Controls:MyCustomControl MyCustomForeground="Blue">
<Controls:MyCustomControl.PrimaryItems>
<Button Content="Test button"/>
</Controls:MyCustomControl.PrimaryItems>
</Controls:MyCustomControl>
</Grid>
我希望Button前景自动为蓝色,因为我在TemplatedControl中设置为MyCustomForeground。
任何提示?
答案 0 :(得分:1)
您是否尝试过{TemplateBinding xxxx}?
<Controls:MyCustomControl MyCustomForeground="{TemplateBinding Foreground}">
<Controls:MyCustomControl.PrimaryItems>
<Button Content="Test button"/>
</Controls:MyCustomControl.PrimaryItems>
</Controls:MyCustomControl>
答案 1 :(得分:0)
我知道,这个很棘手。如果您尝试使用DependencyProperty遗产,这将无法工作(使用UserControl的foreground属性):
<UserControl
x:Class="TestApp1.CustomControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400" Foreground="Blue">
<StackPanel x:Name="PART_Container">
<Button Content="Test"/>
<TextBlock Text="Test"/>
</StackPanel>
</UserControl>
如果您尝试使用此代码段,该按钮的手机模板将覆盖前景=&#34;蓝色&#34;因此它将具有白色(或取决于主题的黑色)前景。请注意,Textblock没有样式,并且不会显示此行为,它将成功从其父UserControl继承蓝色前景。
如何解决这个问题?您似乎声明了自定义依赖项属性MyCustomForeground,因此您可以在DependencyPropertyChanged处理程序中实现逻辑。但是,每当PrimaryItems发生变化时,您还必须应用自定义前景。
这是一个工作样本:
public sealed partial class CustomControl : UserControl
{
public CustomControl()
{
this.InitializeComponent();
}
public Brush MyCustomForeground
{
get { return (Brush)GetValue(MyCustomForegroundProperty); }
set { SetValue(MyCustomForegroundProperty, value); }
}
// Using a DependencyProperty as the backing store for MyCustomForeground. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyCustomForegroundProperty =
DependencyProperty.Register("MyCustomForeground", typeof(Brush), typeof(CustomControl), new PropertyMetadata(null, OnCustomForegroundChanged));
private static void OnCustomForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CustomControl ctrl = (CustomControl)d;
ctrl.ApplyCustomForeground();
}
public UIElement PrimaryItems
{
get { return (UIElement)GetValue(PrimaryItemsProperty); }
set { SetValue(PrimaryItemsProperty, value); }
}
// Using a DependencyProperty as the backing store for PrimaryItems. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PrimaryItemsProperty =
DependencyProperty.Register("PrimaryItems", typeof(UIElement), typeof(CustomControl), new PropertyMetadata(null, OnPrimaryItemsChanged));
private static void OnPrimaryItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CustomControl ctrl = (CustomControl)d;
// PART_Container is where I store my PrimaryItems
ctrl.PART_Container.Children.Clear();
ctrl.PART_Container.Children.Add((UIElement)e.NewValue);
ctrl.ApplyCustomForeground();
}
private void ApplyCustomForeground()
{
// PART_Container is where I store my PrimaryItems
foreach (var child in PART_Container.Children)
{
// Foreground is inherited by Control or TextBlock, or other classes...
// You would be better off using reflection here but that's off topic
if (child is Control)
{
((Control)child).Foreground = MyCustomForeground;
}
else if (child is TextBlock)
{
((TextBlock)child).Foreground = MyCustomForeground;
}
}
}
}