Skip to content

Instantly share code, notes, and snippets.

@nexpr
Created May 2, 2017 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nexpr/9bec5e872f33e27f14a2ccc69935827b to your computer and use it in GitHub Desktop.
Save nexpr/9bec5e872f33e27f14a2ccc69935827b to your computer and use it in GitHub Desktop.
wpf: split grid vertical/horizontal
<Window x:Class="wpf_testproj.Window00"
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:wpf_testproj"
mc:Ignorable="d"
Title="Window00" Height="600" Width="600"
PreviewKeyDown="Window_PreviewKeyDown">
<Grid x:Name="root_grid">
<Grid>
<TextBox />
</Grid>
</Grid>
</Window>
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.Shapes;
namespace wpf_testproj
{
/// <summary>
/// Window00.xaml の相互作用ロジック
/// </summary>
public partial class Window00 : Window
{
public Window00()
{
InitializeComponent();
}
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
var focused = FocusManager.GetFocusedElement(this) as TextBox;
if (focused == null) return;
var grid = focused.Parent as Grid;
// Ctrl-F2
if (e.Key == Key.F2 && Keyboard.Modifiers == ModifierKeys.Control)
{
var new_grid = this.splitVertical(grid);
// focus created textbox
new_grid.Children[0].Focus();
}
// Shift-F2
else if (e.Key == Key.F2 && Keyboard.Modifiers == ModifierKeys.Shift)
{
var new_grid = this.splitHorizontal(grid);
// focus created textbox
new_grid.Children[0].Focus();
}
// Ctrl-F6
else if (e.Key == Key.F6 && Keyboard.Modifiers == ModifierKeys.Control)
{
var sibling = this.destroy(grid);
// focus textbox in left sibling
this.find<TextBox>(sibling)?.Focus();
}
else
{
return;
}
e.Handled = true;
}
/// <summary>
/// 横に追加する
/// </summary>
/// <param name="grid"></param>
/// <returns></returns>
private Grid splitVertical(Grid grid)
{
var new_grid = new Grid();
new_grid.SetValue(Grid.RowProperty, grid.GetValue(Grid.RowProperty));
new_grid.SetValue(Grid.ColumnProperty, grid.GetValue(Grid.ColumnProperty));
new_grid.ColumnDefinitions.Add(new ColumnDefinition { MinWidth = 5 });
new_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
new_grid.ColumnDefinitions.Add(new ColumnDefinition { MinWidth = 5 });
var parent = grid.Parent as Grid;
parent.Children.Remove(grid);
parent.Children.Add(new_grid);
var left = grid;
left.ClearValue(Grid.RowProperty);
left.SetValue(Grid.ColumnProperty, 0);
new_grid.Children.Add(left);
var right = this.generate();
right.SetValue(Grid.ColumnProperty, 2);
new_grid.Children.Add(right);
var splitter = new GridSplitter
{
Width = 1,
Background = new SolidColorBrush(Colors.Gray),
HorizontalAlignment = HorizontalAlignment.Stretch,
};
splitter.SetValue(Grid.ColumnProperty, 1);
new_grid.Children.Add(splitter);
return right;
}
/// <summary>
/// 縦に追加する
/// </summary>
/// <param name="grid"></param>
/// <returns></returns>
private Grid splitHorizontal(Grid grid)
{
var new_grid = new Grid();
new_grid.SetValue(Grid.RowProperty, grid.GetValue(Grid.RowProperty));
new_grid.SetValue(Grid.ColumnProperty, grid.GetValue(Grid.ColumnProperty));
new_grid.RowDefinitions.Add(new RowDefinition { MinHeight = 5 });
new_grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
new_grid.RowDefinitions.Add(new RowDefinition { MinHeight = 5 });
var parent = grid.Parent as Grid;
parent.Children.Remove(grid);
parent.Children.Add(new_grid);
var top = grid;
top.ClearValue(Grid.ColumnProperty);
top.SetValue(Grid.RowProperty, 0);
new_grid.Children.Add(top);
var bottom = this.generate();
bottom.SetValue(Grid.RowProperty, 2);
new_grid.Children.Add(bottom);
var splitter = new GridSplitter
{
Height = 1,
Background = new SolidColorBrush(Colors.Gray),
HorizontalAlignment = HorizontalAlignment.Stretch
};
splitter.SetValue(Grid.RowProperty, 1);
new_grid.Children.Add(splitter);
return bottom;
}
/// <summary>
/// 削除
/// </summary>
/// <param name="grid"></param>
/// <returns></returns>
private Grid destroy(Grid grid)
{
var parent = grid.Parent as Grid;
if (parent == this.root_grid) return null;
var sibling = (Grid)parent.Children.Cast<UIElement>().First(e => e is Grid && e != grid);
sibling.SetValue(Grid.RowProperty, parent.GetValue(Grid.RowProperty));
sibling.SetValue(Grid.ColumnProperty, parent.GetValue(Grid.ColumnProperty));
var grandparent = parent.Parent as Grid;
parent.Children.Clear();
grandparent.Children.Remove(parent);
grandparent.Children.Add(sibling);
return sibling;
}
private Grid generate()
{
return new Grid
{
Children = { new TextBox() }
};
}
private T closest<T>(FrameworkElement elem)
where T : FrameworkElement
{
if (elem == null) return null;
if (elem is T t) return t;
return this.closest<T>(elem.Parent as FrameworkElement);
}
private T find<T>(Grid grid)
where T : FrameworkElement
{
foreach (UIElement i in grid.Children)
{
if (i is T t) return t;
if (i is Grid g)
{
var r = this.find<T>(g);
if (r != null) return r;
}
}
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment