【问题标题】:How to refer to the ItemsPanelTemplate from within an ItemsControl control template如何从 ItemsControl 控件模板中引用 ItemsPanelTemplate
【发布时间】:2014-03-02 21:48:26
【问题描述】:

假设我正在编写一个 ItemsControl 控件模板,并且出于某种原因需要引用 ItemsPanel 实例。由于不在同一个名称范围内,因此没有真正的方法来绑定它。

我正在使用一个自定义项目面板——一个从一个项目滑到下一个项目的轮播式面板——并且希望控制模板中的一个按钮可以向左或向右移动:

<Style TargetType="custom:AnItemsControl">
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <custom:SlideContentPanel />
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="custom:AnItemsControl">
                <Grid>
                    <ItemsPresenter />
                    <Button Content="Next" HorizontalAlignment="Right" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

本例中的Button如何引用项目面板“SlideContentPanel”上的“GoRight()”和属性“CanGoRight”之类的方法?

【问题讨论】:

    标签: c# silverlight xaml windows-phone-7 windows-phone


    【解决方案1】:

    您不能直接引用项目面板实例。但是您可以在 ItemsControl 上定义依赖属性,并在控件加载时在代码隐藏中设置它。然后控件模板可以通过TemplateBinding 引用该属性。

    所以在示例中,“AnItemsControl”应该定义一个“SlideContentPanel”类型的依赖属性:

        public SlideControl()
        {
            DefaultStyleKey = typeof(SlideControl);
            Loaded += SlideControl_Loaded;
        }
    
        public SlideContentPanel TypedPanel
        {
            get { return (SlideContentPanel)GetValue(TypedPanelProperty); }
            set { SetValue(TypedPanelProperty, value); }
        }
        public static readonly DependencyProperty SlidePanelProperty =
            DependencyProperty.Register("TypedPanel", typeof(SlideContentPanel), typeof(AnItemsControl), new PropertyMetadata(null));
    

    现在,当控件加载时,使用VisualTreeHelper 定位面板,并设置依赖属性:

        public AnItemsControl()
        {
            DefaultStyleKey = typeof(AnItemsControl);
            Loaded += AnItemsControl_Loaded;
        }
    
        private void AnItemsControl_Loaded(object sender, RoutedEventArgs e)
        {
            TypedPanel = FindItemsPanel<SlideContentPanel>(this);
        }
    
        private T FindItemsPanel<T>(FrameworkElement visual)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
            {
                FrameworkElement child = VisualTreeHelper.GetChild(visual, i) as FrameworkElement;
                if (child != null)
                {
                    if (child is T && VisualTreeHelper.GetParent(child) is ItemsPresenter)
                    {
                        object temp = child;
                        return (T)temp;
                    }
    
                    T panel = FindItemsPanel<T>(child);
                    if (panel != null)
                    {
                        object temp = panel;
                        return (T)temp;
                    }
                }
            }
            return default(T);
        }
    

    现在“AnItemsControl”的控件模板中的按钮可以通过使用模板父项中的“TypedPanel”属性来引用面板:

    <Button Content="Next" HorizontalAlignment="Right" 
            Visibility="{Binding RelativeSource={RelativeSource TemplatedParent},
                                 Path=TypedPanel.CanGoRight,
                                 Converter={StaticResource BoolToVisibilityConverter}}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Tap">
                <ei:CallMethodAction 
                    TargetObject="{Binding RelativeSource={RelativeSource TemplatedParent},Path=TypedPanel}" 
                    MethodName="GoRight" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>
    

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 2013-03-01
      • 1970-01-01
      相关资源
      最近更新 更多