WPF - ItemTemplate не работает должным образом - PullRequest
4 голосов
/ 19 марта 2009

У меня есть UserControl, который я использую для отображения списка UIElement с. Элемент управления состоит из одного 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.

Любая помощь будет очень полезна. Спасибо.

Ответы [ 5 ]

6 голосов
/ 19 марта 2009

Nir является правильным, ItemsControl добавит элемент непосредственно к его Panel, если они являются элементами UIE. Я не смог найти упоминания об этом поведении в MSDN, но доктор WPF упоминает об этом в своей статье о контейнерах предметов :

Если UIElement добавлен в коллекцию Items явного экземпляра ItemsControl (в отличие от экземпляра производного класса, такого как ListBox), он станет прямым потомком панели элементов. Если не-UIElement добавлен, он будет заключен в ContentPresenter.

Ваше решение, вероятно, состоит в том, чтобы вместо этого использовать ListBox и установить ItemContainerStyle на новый Style для ListBoxItem, и в этом стиле использовать ControlTemplate с вашим Border. 1017 *

4 голосов
/ 11 августа 2009

Нир прав, эта пользовательская реализация ItemsControl решит проблему и позволит использовать ваш собственный ItemTemplate:

public class ItemsControlForUIElement : ItemsControl
{
   protected override DependencyObject GetContainerForItemOverride()
   {
       return new ContentPresenter();
   }
   protected override bool IsItemItsOwnContainerOverride(object item)
   {
       return false;
   }
}
4 голосов
/ 19 марта 2009

Это потому, что это список элементов UIElement, шаблон элемента применяется, только если элементы не могут быть отображены напрямую.

2 голосов
/ 29 мая 2011

Роберт Макни прибил причину по голове. Его решение включает использование шаблона управления, который может быть излишним для данного сценария. В качестве альтернативы используйте ListBox - установите ItemContainerStyle на новый стиль для ListBoxItem, и в этом стиле установите ContentTemplate на DataTemplate, который вы хотели использовать в ListBox ItemTemplate .

0 голосов
/ 20 марта 2009

Если вы установите свойство DataType на DataTemplate, оно начнет работать.

...