如何从ItemsControl控件模板中引用ItemsPanelTemplate

时间:2014-03-02 21:48:26

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

假设我正在编写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”?

1 个答案:

答案 0 :(得分:0)

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

所以在这个例子中,&#34; AnItemsControl&#34;应定义类型&#34; SlideContentPanel&#34;:

的依赖项属性
    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);
    }

现在,&#34; AnItemsControl&#34;控件模板中的按钮可以通过使用&#34; TypedPanel&#34;来引用面板。模板化父级中的属性:

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