WPF:有没有类似于“SplitContainer”的标准控件?

19

在WPF中是否有类似于Windows Forms SplitContainer的标准控件?

我对网格有点困惑,因为控件似乎不在单元格内,而是在上面 :s。

我谷歌了一些东西,但不知道在搜索框中确切地应该写什么...

5个回答

30

这是一个制作水平SplitContainer的示例,它使用了Grid和GridSplitter,就像SnowBear所说的那样:

<Window x:Class="JobFinder1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="JobFinder1" Height="350" Width="525" AllowsTransparency="False">
    <Grid Name="gridMain">
        <Grid.RowDefinitions>
            <RowDefinition Height="26" />
            <RowDefinition />
            <RowDefinition Height="1"/>
            <RowDefinition />
        </Grid.RowDefinitions>

        <ToolBar Height="26" VerticalAlignment="Stretch" HorizontalAlignment="Left" />
        <ListView Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
        <GridSplitter Background="DarkGray"  ResizeDirection="Rows" Grid.Row="2" 
                      HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                      ResizeBehavior="PreviousAndNext" />
        <ListView Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
    </Grid>
</Window>

24

1

这是一个简单的控件,需要更多的改进,但它完成了它的工作...

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Data;
        using System.Windows.Documents;
        using System.Windows.Input;
        using System.Windows.Media;
        using System.Windows.Media.Imaging;
        using System.Windows.Navigation;
        using System.Windows.Shapes;
        using System.Windows.Markup;

        namespace Infinity.Shell.Controls.Docking
        {
            /// <summary>
            /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
            ///
            /// Step 1a) Using this custom control in a XAML file that exists in the current project.
            /// Add this XmlNamespace attribute to the root element of the markup file where it is 
            /// to be used:
            ///
            ///     xmlns:MyNamespace="clr-namespace:Infinity.Shell.Controls.Docking"
            ///
            ///
            /// Step 1b) Using this custom control in a XAML file that exists in a different project.
            /// Add this XmlNamespace attribute to the root element of the markup file where it is 
            /// to be used:
            ///
            ///     xmlns:MyNamespace="clr-namespace:Infinity.Shell.Controls.Docking;assembly=Infinity.Shell.Controls.Docking"
            ///
            /// You will also need to add a project reference from the project where the XAML file lives
            /// to this project and Rebuild to avoid compilation errors:
            ///
            ///     Right click on the target project in the Solution Explorer and
            ///     "Add Reference"->"Projects"->[Browse to and select this project]
            ///
            ///
            /// Step 2)
            /// Go ahead and use your control in the XAML file.
            ///
            ///     <MyNamespace:SplitContainer/>
            ///
            /// </summary>

            public class SplitContainer : Control
            {
                public Orientation Orientation
                {
                    get { return (Orientation)GetValue(OrientationProperty); }
                    set { SetValue(OrientationProperty, value); }
                }

                // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty OrientationProperty =
                    DependencyProperty.Register("Orientation", typeof(Orientation), typeof(SplitContainer), new PropertyMetadata(Orientation.Horizontal));

                public UIElement FirstChild
                {
                    get { return (UIElement)GetValue(FirstChildProperty); }
                    set { SetValue(FirstChildProperty, value); }
                }

                // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty FirstChildProperty =
                    DependencyProperty.Register("FirstChild", typeof(UIElement), typeof(SplitContainer), new PropertyMetadata(null));

                public UIElement SecondChild
                {
                    get { return (UIElement)GetValue(SecondChildProperty); }
                    set { SetValue(SecondChildProperty, value); }
                }

                // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty SecondChildProperty =
                    DependencyProperty.Register("SecondChild", typeof(UIElement), typeof(SplitContainer), new PropertyMetadata(null));


                static SplitContainer()
                {
                    DefaultStyleKeyProperty.OverrideMetadata(typeof(SplitContainer), new FrameworkPropertyMetadata(typeof(SplitContainer)));
                }

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

        <Style TargetType="{x:Type dock:SplitContainer}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type dock:SplitContainer}">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>

                                <Grid.ColumnDefinitions> <!--Horizontal -->
                                    <ColumnDefinition/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>

                                <Grid x:Name="PART_FirstChildGrid"
                                      Grid.Column="0"
                                      Grid.Row="0"
                                      Grid.RowSpan="3">
                                    <ContentPresenter Content="{TemplateBinding FirstChild}"/>
                                </Grid>

                                <GridSplitter x:Name="PART_Splitter"
                                              Grid.Column="1"
                                              Grid.Row="0"
                                              Grid.RowSpan="3"
                                              Grid.ColumnSpan="1"
                                              Width="5"
                                              VerticalAlignment="Stretch"
                                              HorizontalAlignment="Center"
                                              ShowsPreview="True"/>

                                <Grid x:Name="PART_SecondChildGrid"
                                      Grid.Column="2"
                                      Grid.Row="0"
                                      Grid.RowSpan="3">
                                    <ContentPresenter Content="{TemplateBinding SecondChild}"/>
                                </Grid>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Orientation" Value="Vertical">
                                <Setter TargetName="PART_FirstChildGrid" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="PART_FirstChildGrid" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="PART_FirstChildGrid" Property="Grid.ColumnSpan" Value="3"/>
                                <Setter TargetName="PART_FirstChildGrid" Property="Grid.RowSpan" Value="1"/>

                                <Setter TargetName="PART_Splitter" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="PART_Splitter" Property="Grid.Row" Value="1"/>
                                <Setter TargetName="PART_Splitter" Property="Grid.ColumnSpan" Value="3"/>
                                <Setter TargetName="PART_Splitter" Property="Grid.RowSpan" Value="1"/>
                                <Setter TargetName="PART_Splitter" Property="VerticalAlignment" Value="Center"/>
                                <Setter TargetName="PART_Splitter" Property="HorizontalAlignment" Value="Stretch"/>
                                <Setter TargetName="PART_Splitter" Property="Width" Value="Auto"/>
                                <Setter TargetName="PART_Splitter" Property="Height" Value="5"/>

                                <Setter TargetName="PART_SecondChildGrid" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="PART_SecondChildGrid" Property="Grid.Row" Value="2"/>
                                <Setter TargetName="PART_SecondChildGrid" Property="Grid.ColumnSpan" Value="3"/>
                                <Setter TargetName="PART_SecondChildGrid" Property="Grid.RowSpan" Value="1"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Infinity.Shell.Controls.Text;assembly=Infinity.Shell"
            xmlns:dock="clr-namespace:Infinity.Shell.Controls.Docking;assembly=Infinity.Shell"
x:Class="Infinity.MainWindow"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="499.573" Background="#FF1E1E1E">
        <Grid>
            <dock:SplitContainer Orientation="Vertical">
                <dock:SplitContainer.FirstChild>
                    <dock:SplitContainer>
                        <dock:SplitContainer.FirstChild>
                            <Button Content="First Child Button"/>
                        </dock:SplitContainer.FirstChild>
                        <dock:SplitContainer.SecondChild>
                            <Button Content="Second Child Button"/>
                        </dock:SplitContainer.SecondChild>
                    </dock:SplitContainer>
                </dock:SplitContainer.FirstChild>
                <dock:SplitContainer.SecondChild>
                    <Button Content="First Splitter Second Child"/>
                </dock:SplitContainer.SecondChild>
            </dock:SplitContainer>
        </Grid>


    </Window>

1

Grid + GridSplitter 很麻烦。虽然它们很容易使用,但会使 Xaml 变得丑陋,并且在设计阶段经常需要重新排列时难以维护。

您可能正在寻找这样的解决方案。

http://wpfsplitcontainer.codeplex.com/

注意:在使用之前,请检查许可证。

许可证为GPL v2。 - Jeson Martajaya

0

另一个,没有GPL许可证

http://www.codeproject.com/Articles/293396/Teh-Simple-but-Useful-WPF-Container

这个来自微软的tutorialGridSplitter也非常方便。这里有一个扩展示例,包括水平和垂直调整大小。(注意GridSplitter的HorizontalAligmentResizeDirection)。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto" />
        <RowDefinition MinHeight="70" />
    </Grid.RowDefinitions>
    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition MinWidth="70" />
        </Grid.ColumnDefinitions>
        <DockPanel Grid.Column="0" Background="LightBlue" ></DockPanel>
        <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" ResizeDirection="Columns" Height="Auto" Width="3" />
        <Grid Grid.Column="2" Background="PaleGoldenrod" ></Grid>
    </Grid>
    <GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" ResizeDirection="Rows" Height="3" Width="Auto" />
    <DockPanel Grid.Row="2" Background="Green" ></DockPanel>
</Grid>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接