2

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

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

1 回答 1

1

直接的答案是你需要一个ItemsPresenterin your 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您已经拥有的 aContentControlPART_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);
    }
 }
于 2009-08-26T06:57:59.247 回答