#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

136 lines
5.2 KiB

// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Designer.Controls;
using ICSharpCode.WpfDesign.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
/// <summary>
/// Allows arranging the rows/column on a grid.
/// </summary>
[ExtensionFor(typeof(Grid))]
[ExtensionServer(typeof(LogicalOrExtensionServer<PrimarySelectionExtensionServer, PrimarySelectionParentExtensionServer>))]
public class GridAdornerProvider : AdornerProvider
{
sealed class RowSplitterPlacement : AdornerPlacement
{
readonly RowDefinition row;
public RowSplitterPlacement(RowDefinition row) { this.row = row; }
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize)
{
adorner.Arrange(new Rect(-(GridRailAdorner.RailSize + GridRailAdorner.RailDistance),
row.Offset - GridRailAdorner.SplitterWidth / 2,
GridRailAdorner.RailSize + GridRailAdorner.RailDistance + adornedElementSize.Width,
GridRailAdorner.SplitterWidth));
}
}
sealed class ColumnSplitterPlacement : AdornerPlacement
{
readonly ColumnDefinition column;
public ColumnSplitterPlacement(ColumnDefinition column) { this.column = column; }
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize)
{
adorner.Arrange(new Rect(column.Offset - GridRailAdorner.SplitterWidth / 2,
-(GridRailAdorner.RailSize + GridRailAdorner.RailDistance),
GridRailAdorner.SplitterWidth,
GridRailAdorner.RailSize + GridRailAdorner.RailDistance + adornedElementSize.Height));
}
}
AdornerPanel adornerPanel = new AdornerPanel();
GridRailAdorner topBar, leftBar;
protected override void OnInitialized()
{
leftBar = new GridRailAdorner(this.ExtendedItem, adornerPanel, Orientation.Vertical);
topBar = new GridRailAdorner(this.ExtendedItem, adornerPanel, Orientation.Horizontal);
RelativePlacement rp = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Stretch);
rp.XOffset -= GridRailAdorner.RailDistance;
AdornerPanel.SetPlacement(leftBar, rp);
rp = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Top);
rp.YOffset -= GridRailAdorner.RailDistance;
AdornerPanel.SetPlacement(topBar, rp);
adornerPanel.Children.Add(leftBar);
adornerPanel.Children.Add(topBar);
this.Adorners.Add(adornerPanel);
CreateSplitter();
this.ExtendedItem.PropertyChanged += OnPropertyChanged;
base.OnInitialized();
}
protected override void OnRemove()
{
this.ExtendedItem.PropertyChanged -= OnPropertyChanged;
base.OnRemove();
}
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "RowDefinitions" || e.PropertyName == "ColumnDefinitions") {
CreateSplitter();
}
}
readonly List<GridSplitterAdorner> splitterList = new List<GridSplitterAdorner>();
/// <summary>
/// flag used to ensure that the asynchronus splitter creation is only enqueued once
/// </summary>
bool requireSplitterRecreation;
void CreateSplitter()
{
if (requireSplitterRecreation) return;
requireSplitterRecreation = true;
// splitter creation is delayed to prevent unnecessary splitter re-creation when multiple
// changes to the collection are done.
// It also ensures that the Offset property of new rows/columns is initialized when the splitter
// is added.
Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Loaded, // Loaded = after layout, but before input
(Action)delegate {
requireSplitterRecreation = false;
foreach (GridSplitterAdorner splitter in splitterList) {
adornerPanel.Children.Remove(splitter);
}
splitterList.Clear();
Grid grid = (Grid)this.ExtendedItem.Component;
IList<DesignItem> col = this.ExtendedItem.Properties["RowDefinitions"].CollectionElements;
for (int i = 1; i < grid.RowDefinitions.Count; i++) {
RowDefinition row = grid.RowDefinitions[i];
GridRowSplitterAdorner splitter = new GridRowSplitterAdorner(this.ExtendedItem, col[i-1], col[i]);
AdornerPanel.SetPlacement(splitter, new RowSplitterPlacement(row));
adornerPanel.Children.Add(splitter);
splitterList.Add(splitter);
}
col = this.ExtendedItem.Properties["ColumnDefinitions"].CollectionElements;
for (int i = 1; i < grid.ColumnDefinitions.Count; i++) {
ColumnDefinition column = grid.ColumnDefinitions[i];
GridColumnSplitterAdorner splitter = new GridColumnSplitterAdorner(this.ExtendedItem, col[i-1], col[i]);
AdornerPanel.SetPlacement(splitter, new ColumnSplitterPlacement(column));
adornerPanel.Children.Add(splitter);
splitterList.Add(splitter);
}
});
}
}
}