2009-03-19 2 views
4

У меня есть UserControl, который я использую для отображения списка UIElement. Управления состоит из одного ItemsControl с его ItemPanelTemplate переключается для горизонтального StackPanel, его ItemsSource привязан к DependencyProperty выставленного UserControl и его ItemTemplate множества в UserControl.Resources.WPF - ItemTemplate действует не так, как ожидалось

Все работает отлично, за исключением 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> 

Кнопки выглядят прекрасно, но не внутри квадратной границы 200 пикселей.

Любая помощь была бы превосходно оценена. Спасибо.

ответ

4

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

+0

Что вы предложите тогда? – Stimul8d

+0

Кроме того, если я поменяю ItemsControl для Listbox, тогда они отображают как ожидалось, поэтому я не уверен, что вы прямо там – Stimul8d

+0

Кажется, я должен есть свои слова! Спасибо, Нир. – Stimul8d

6

Nir правильный, ItemsControl будет добавлять товар непосредственно к его Panel, если они являются UIElements. Я не мог найти ни одного упоминания такого поведения в MSDN, но доктор WPF упоминает его в his article on item containers:

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

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

+0

Ну, это не сумасшедшее поведение. Спасибо, что Роберт, я дам Ниру правильный ответ и проголосую за тебя. Стыдно, что у вас не может быть более одного правильного ответа? – Stimul8d

-1

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

4

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

public class ItemsControlForUIElement : ItemsControl 
{ 
    protected override DependencyObject GetContainerForItemOverride() 
    { 
     return new ContentPresenter(); 
    } 
    protected override bool IsItemItsOwnContainerOverride(object item) 
    { 
     return false; 
    } 
} 
2

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