代码之家  ›  专栏  ›  技术社区  ›  SonofNun

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

  •  0
  • SonofNun  · 技术社区  · 9 年前

    在自定义TemplatedControl中,我有一个ItemsControl,它填充在自定义TemplateControl之外。我希望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 回复  |  直到 9 年前
        1
  •  1
  •   pleasereset    9 年前

    您尝试过{TemplateBinding xxxx}吗?

    <Controls:MyCustomControl MyCustomForeground="{TemplateBinding Foreground}">
        <Controls:MyCustomControl.PrimaryItems>
            <Button Content="Test button"/>
        </Controls:MyCustomControl.PrimaryItems>
    </Controls:MyCustomControl>
    
        2
  •  0
  •   pleasereset    9 年前

    我明白了,这个很棘手。如果您尝试使用DependencyProperty继承,这将不起作用(使用UserControl的前台属性):

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

    如果您尝试此片段,手机的按钮模板将覆盖前景=“蓝色”,因此它将具有白色(或黑色,取决于主题)前景。请注意,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;
                }
            }
        }
    }