2009-08-23 2 views
2

Я хочу, чтобы создать пользовательский элемент управления, так что я могу сделать что-то вроде этого:WPF пользовательских элементов управления для бок о бок Layout

<SideBySide> 
    <StackPanel SideBySide.Left="True">...</StackPanel> 
    <StackPanel SideBySide.Right="False">...</StackPanel> 
</SideBySide> 

Я собираюсь использовать это повсюду, с явно более варианты (размер и т. д.).

Я рассмотрел использование подкласса Panel, но это не кажется правильным (есть понятие выбранного элемента слева и справа).

Итак, я пытаюсь использовать подкласс ItemsControl - теперь кто-нибудь знает, как поместить элементы в шаблон управления для ItemsControl?

Это сокращенный шаблон для SideBySide:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfCustomControlLibrary1"> 
    <Style TargetType="{x:Type local:SideBySideControl}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:SideBySideControl}"> 
        <Border Background="{TemplateBinding Background}" 
          BorderBrush="{TemplateBinding BorderBrush}" 
          BorderThickness="{TemplateBinding BorderThickness}"> 
         <Grid> 
          <Grid.Resources> 
           <Style TargetType="{x:Type Rectangle}"> 
            <Setter Property="Margin" 
              Value="5" /> 
           </Style> 
          </Grid.Resources> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition /> 
           <ColumnDefinition Width="Auto" /> 
           <ColumnDefinition /> 
          </Grid.ColumnDefinitions> 
          <Grid Grid.Column="0" 
            VerticalAlignment="Stretch"> 
           <!-- PART_LeftContent goes here --> 
          </Grid> 
          <GridSplitter Width="3" 
              Grid.Column="1" 
              HorizontalAlignment="Center" 
              VerticalAlignment="Stretch" 
              ShowsPreview="False"> 
          </GridSplitter> 
          <Grid Grid.Column="2"> 
           <!-- PART_RightContent goes here --> 
          </Grid> 
         </Grid> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

ответ

1

Прямой ответ в том, что вам нужен ItemsPresenter в вашем ControlTemplate, который будет выглядеть примерно так:

<ItemsControl x:Class="ItemsControlExample" 
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <ItemsControl.Template> 
     <ControlTemplate TargetType="ItemsControl"> 
      <Border SnapsToDevicePixels="True"> 
       <!-- Collection items are displayed by the ItemsPresenter. --> 
       <ItemsPresenter SnapsToDevicePixels="True" /> 
      </Border> 
     </ControlTemplate> 
    </ItemsControl.Template> 

    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <!-- Replace the default vertical StackPanel with horizontal. --> 
      <StackPanel Orientation="Horizontal" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 

    <ItemsControl.ItemContainerStyle> 
     <Style TargetType="..."> 
      <!-- The same container style applies to all items so where do you put the splitter? --> 
     </Style> 
    </ItemsControl.ItemContainerStyle>  

</ItemsControl> 

Но это должно теперь очевидно, что ItemsControl не соответствует вашему варианту использования. Тем не менее, вы можете реализовать его в качестве Control с помощью ControlTemplate у вас уже есть с ContentControl в PART_LeftContent и PART_RightContent ячеек сетки:

<!-- LeftSideContent is a DependencyProperty of type object --> 
<ContentControl x:Name="LeftContentControl" Content="{TemplateBinding LeftSideContent}" /> 

Затем расширить свой код для обработки ContentControl событий мыши, чтобы выбрать и добавить триггеры стиля для выбранного внешнего вида, но это довольно простой материал. Если вы не внедрили бесполезные элементы управления, прежде чем вы должны знать, что вы не можете определить обратные вызовы событий в шаблоне, но вместо этого нужно их привязать в своем коде:

public override void OnApplyTemplate() 
{ 
    base.OnApplyTemplate(); 

    ContentControl lc = (ContentControl)base.GetTemplateChild("LeftContentControl")); 
    // check for null in case the active template doesn't have a 'LeftContentControl' element 
    if (lc != null) 
    { 
     // Use these events to set SelectedItem DependencyProperty and trigger selected item 
     // highlight style. Don't forget to capture the mouse for proper click behavior. 
     lc.MouseDown += new MouseButtonEventHandler(LeftSide_MouseDown); 
     lc.MouseUp += new MouseButtonEventHandler(LeftSide_MouseUp); 
    } 
} 
+0

+1 это именно то, что я находясь в поиске. У вас есть ссылки на полные образцы? – bendewey