wpf: можно ли использовать разветвитель сетки вне сетки? - PullRequest
2 голосов
/ 13 мая 2009

У меня есть StackPanel, и он идеально подходит для размещения столбцов, которые пользователь добавляет во время выполнения. Но я бы хотел, чтобы размер столбцов можно было изменять, и я читал об элементе управления GridSplitter. Вот что мне интересно: Является ли GridSplitter заменой wpf для сплиттера WinForms? Другими словами, является ли это де-факто способом, позволяющим пользователям изменять размеры областей окна? Это работает только внутри Grid? Если у меня есть элементы внутри стековой или док-панели, могу ли я по-прежнему использовать гридсплиттер так же, как я использовал сплиттер в WinForms? Если мне нужно использовать Grid, как я могу заставить его вести себя так же, как StackPanel? (надеюсь, до этого не дойдет)

Ответы [ 3 ]

2 голосов
/ 13 мая 2009

GridSplitter работает только в Grid и является самым простым способом, позволяющим пользователям изменять размеры элементов управления. Что вы имеете в виду, что вы хотите, чтобы ваша сетка (с сеточными сплиттерами) вела себя как панель стека? Панель стека будет точно соответствовать каждому из его дочерних элементов, а сетка с сеточными разделителями предоставит ее пользователю.

1 голос
/ 14 мая 2009

Ниже представлен пользовательский элемент управления, который позволяет добавлять элементы в виде столбцов. Между столбцами расположены разделители сетки. Пользователи могут нажать кнопку Удалить, чтобы удалить добавленные столбцы, и столбцы могут быть добавлены с помощью кода позади. Дайте мне знать, если это то, что вы искали.

Пользовательский контроль SmartGrid XAML:

<UserControl x:Class="SmartGridDemo.SmartGrid"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid Name="_grid">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
    </Grid>
</UserControl>  

Пользовательский контроль SmartGrid код позади:

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace SmartGridDemo
{
    public partial class SmartGrid : UserControl
    {
        public SmartGrid()
        {
            InitializeComponent();
        }

        public void Add(UIElement child)
        {
            int columnIndex = _grid.ColumnDefinitions.Count();

            _grid.ColumnDefinitions.Add(
                new ColumnDefinition() 
                {
                    Width = new GridLength(columnIndex == 0 ? 0 :5)
                });

            GridSplitter gridSplitter =
                new GridSplitter()
                {
                    HorizontalAlignment = HorizontalAlignment.Stretch,
                    VerticalAlignment = VerticalAlignment.Stretch,
                    ResizeDirection = GridResizeDirection.Columns,
                    Background = Brushes.Black
                };

            _grid.Children.Add(gridSplitter);
            Grid.SetColumn(gridSplitter, columnIndex);
            Grid.SetRow(gridSplitter, 0);
            Grid.SetRowSpan(gridSplitter, 2);

            columnIndex++;

            _grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });

            Button button = new Button();
            button.Content = "Delete";
            button.Tag = new TagTuple() {Child = child, GridSplitter = gridSplitter};
            button.Click += new RoutedEventHandler(DeleteButton_Click);

            _grid.Children.Add(button);
            Grid.SetColumn(button, columnIndex);
            Grid.SetRow(button, 0);

            _grid.Children.Add(child);
            Grid.SetColumn(child, columnIndex);
            Grid.SetRow(child, 1);
        }

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            int columnIndex = Grid.GetColumn(button);
            TagTuple tagTuple = button.Tag as TagTuple;
            _grid.Children.Remove(tagTuple.GridSplitter);
            _grid.Children.Remove(tagTuple.Child);
            _grid.Children.Remove(button as UIElement);

            _grid.ColumnDefinitions.RemoveAt(_grid.ColumnDefinitions.Count() - 1);
            _grid.ColumnDefinitions.RemoveAt(_grid.ColumnDefinitions.Count() - 1);

            foreach (UIElement child in _grid.Children)
            { 
                int columnIndexForChild = Grid.GetColumn(child);
                if (columnIndexForChild > columnIndex)
                {
                    Grid.SetColumn(child, columnIndexForChild - 2);
                }
            }
        }

        private class TagTuple
        {
            public GridSplitter GridSplitter { get; set; }
            public UIElement Child { get; set; }
        }
    }
}

Демонстрационный код, добавьте текст в TextBox и нажмите кнопку «Добавить», чтобы добавить новые столбцы, XAML:

<Window x:Class="SmartGridDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SmartGridDemo"    
    Title="SmartGridDemo" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <TextBox Name="_texBox" Grid.Row="0" Grid.Column="0" />
        <Button Content="Add" Click="AddButton_Click" Grid.Row="0" Grid.Column="1" />
        <local:SmartGrid x:Name="_smartGrid" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" />
    </Grid>
</Window>

Демо, за кодом:

using System;
using System.Windows;
using System.Windows.Controls;

namespace SmartGridDemo
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            _smartGrid.Add(new TextBlock() { Text = "AAA" });
            _smartGrid.Add(new TextBlock() { Text = "BBB" });
            _smartGrid.Add(new TextBlock() { Text = "CCC" });
            _smartGrid.Add(new TextBlock() { Text = "DDD" });
            _smartGrid.Add(new TextBlock() { Text = "EEE" });
            _smartGrid.Add(new TextBlock() { Text = "FFF" });
        }

        private void AddButton_Click(object sender, RoutedEventArgs e)
        {
            _smartGrid.Add(new TextBlock() { Text = _texBox.Text });
        }
    }
}
0 голосов
/ 12 августа 2009

Вот WPF SplitContainer с открытым исходным кодом: [http://wpfsplitcontainer.codeplex.com/]

...