2009-08-23 3 views
2

Je veux créer un contrôle personnalisé pour que je puisse faire quelque chose comme ceci:WPF contrôle personnalisé pour Side by Side Mise en page

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

Je vais utiliser ce dans tous les sens, avec évidemment plus options (dimensionnement, etc.).

J'ai envisagé d'utiliser une sous-classe Panel, mais cela ne semble pas correct (il y a une notion d'élément sélectionné entre la gauche et la droite).

Donc, j'essaie d'utiliser une sous-classe ItemsControl - maintenant, quelqu'un sait comment mettre les éléments dans un modèle de contrôle pour un ItemsControl?

Ceci est un modèle abrégé pour la 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> 

Répondre

1

La réponse directe est que vous avez besoin d'un ItemsPresenter dans votre ControlTemplate, qui ressemblerait à quelque chose comme ceci:

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

Mais il faut Soyez évident maintenant que ItemsControl ne correspond pas à votre cas d'utilisation. Cependant, vous pouvez le mettre en œuvre en tant que Control utilisant le ControlTemplate vous avez déjà avec ContentControl les cellules grille PART_LeftContent et PART_RightContent:

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

étendre ensuite votre code pour gérer les événements de souris ContentControl afin de sélectionner et ajouter des déclencheurs de style pour l'apparence sélectionnée, mais c'est assez simple. Si vous n'avez pas implémenté des contrôles sans apparence avant de savoir que vous ne pouvez pas définir les rappels d'événements dans le modèle, vous devez les placer dans votre code:

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 est exactement ce que je suis à la recherche de. Avez-vous des liens pour compléter des échantillons? – bendewey

Questions connexes