4

我有一个UserControl用来显示UIElements 列表的。该控件由一个单独的控件组成,ItemsControl它被ItemPanelTemplate切换为水平StackPanel,它ItemsSource绑定到由DependencyProperty暴露的UserControl和它ItemTemplate在 中的集合UserControl.Resources

一切正常,除了ItemTemplate从未得到应用,我不明白为什么。完整来源如下。

UserControl.xaml -

<UserControl x:Name="UC" x:FieldModifier="private" x:Class="ContentSliderControl.ContentSlider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>

    <DataTemplate x:Key="pageTemplate">
        <Border CornerRadius="10" Padding="5" Height="200" Width="200" Background="#333">
            <ContentControl Content="{Binding}"/>
        </Border>
    </DataTemplate>

    <ItemsPanelTemplate x:Key="template">
        <StackPanel IsItemsHost="True"
            Orientation="Horizontal"
            ScrollViewer.HorizontalScrollBarVisibility="Disabled"
            ScrollViewer.VerticalScrollBarVisibility="Disabled"/>
    </ItemsPanelTemplate>
</UserControl.Resources>

<ItemsControl ItemsPanel="{StaticResource template}" 
              ItemTemplate="{StaticResource pageTemplate}" 
              ItemsSource="{Binding ElementName=UC,Path=Pages}"/>

UserControl.xaml.cs -

[ContentProperty("Pages")]
public partial class ContentSlider : UserControl
{


    public List<UIElement> Pages
    {
        get { return (List<UIElement>)GetValue(PagesProperty); }
        //set { SetValue(PagesProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Pages.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PagesProperty =
        DependencyProperty.Register("Pages", typeof(List<UIElement>), typeof(ContentSlider), new UIPropertyMetadata(null));



    public ContentSlider()
    {
        InitializeComponent();
    }
}

}

我像这样在主窗口中使用控件-

    <slider:ContentSlider >
    <slider:ContentSlider.Pages>
        <Button>1</Button>
        <Button>2</Button>
        <Button>3</Button>
        <Button>4</Button>
    </slider:ContentSlider.Pages>
</slider:ContentSlider>

按钮看起来不错,但不在 200px 方形边框内。

任何帮助将不胜感激。谢谢。

4

5 回答 5

6

Nir 是正确的,如果它们是 UIElements ,ItemsControl将直接向其添加项目。Panel我在 MSDN 中找不到任何关于这种行为的提及,但 WPF 博士在他关于项目容器的文章中提到了它:

如果将 UIElement 添加到显式 ItemsControl 实例的 Items 集合(与 ListBox 等派生类的实例相反),它将成为项目面板的直接子项。如果添加了非 UIElement,它将被包装在 ContentPresenter 中。

您的解决方案可能是改用 a ListBox,并将其设置ItemContainerStyle为新Style的 for ListBoxItem,并在该样式中将 aControlTemplate与您Border一起使用。

于 2009-03-19T18:24:13.840 回答
4

因为是 UIElement 的列表,只有在 item 不能直接显示的情况下才会应用 item 模板。

于 2009-03-19T11:41:42.927 回答
4

Nir 是对的,这个自定义 ItemsControl 实现将解决问题并让您使用自己的 ItemTemplate:

public class ItemsControlForUIElement : ItemsControl
{
   protected override DependencyObject GetContainerForItemOverride()
   {
       return new ContentPresenter();
   }
   protected override bool IsItemItsOwnContainerOverride(object item)
   {
       return false;
   }
}
于 2009-08-11T03:37:00.933 回答
2

罗伯特·麦克尼(Robert Macnee)将原因钉在了头上。他的解决方案涉及使用控制模板,这对于给定的场景可能是多余的。或者,使用ListBox- 将 设置ItemContainerStyle为 的新样式ListBoxItem,并在该样式中,将 设置为ContentTemplate要在DataTemplate中使用的ListBox ItemTemplate

于 2011-05-28T22:46:38.037 回答
-1

如果您在 上设置DataType属性,DataTemplate它将开始工作。

于 2009-03-20T17:51:34.893 回答