并排布局的WPF自定义控件

时间:2009-08-23 22:28:52

标签: wpf listcontrol

我想创建一个自定义控件,以便我可以执行以下操作:

<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 个答案:

答案 0 :(得分:1)

直接的答案是,ControlTemplate中需要ItemsPresenter,看起来像这样:

<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 PART_LeftContentPART_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);
    }
 }

然后扩展您的代码以处理{{1}}鼠标事件,以便为所选外观选择和添加样式触发器,但这非常简单。如果你没有实现无外观控件,你应该知道你不能在模板中定义事件回调,而是必须将它们挂钩在你的代码中:

{{1}}