Created
May 2, 2017 04:13
-
-
Save nexpr/9bec5e872f33e27f14a2ccc69935827b to your computer and use it in GitHub Desktop.
wpf: split grid vertical/horizontal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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