获取ItemsControl子项以在WinRT中继承前台

时间:2015-02-25 15:34:29

标签: windows-runtime custom-controls windows-8.1

在自定义的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。

任何提示?

2 个答案:

答案 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;
            }
        }
    }
}