1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
5
using System.Diagnostics;
6
using System.Globalization;
9
using System.Windows.Controls;
10
using System.Windows.Input;
11
using System.Windows.Media;
12
using ICSharpCode.WpfDesign.XamlDom;
13
using ICSharpCode.WpfDesign.Adorners;
15
namespace ICSharpCode.WpfDesign.Designer.Controls
18
/// Adorner that displays the blue bar next to grids that can be used to create new rows/column.
20
public class GridRailAdorner : FrameworkElement
22
static GridRailAdorner()
24
bgBrush = new SolidColorBrush(Color.FromArgb(0x35, 0x1E, 0x90, 0xff));
29
readonly DesignItem gridItem;
31
readonly AdornerPanel adornerPanel;
32
readonly GridSplitterAdorner previewAdorner;
33
readonly Orientation orientation;
34
readonly GridUnitSelector unitSelector;
36
static readonly SolidColorBrush bgBrush;
38
public const double RailSize = 10;
39
public const double RailDistance = 6;
40
public const double SplitterWidth = 10;
42
bool displayUnitSelector; // Indicates whether Grid UnitSeletor should be displayed.
44
public GridRailAdorner(DesignItem gridItem, AdornerPanel adornerPanel, Orientation orientation)
46
Debug.Assert(gridItem != null);
47
Debug.Assert(adornerPanel != null);
49
this.gridItem = gridItem;
50
this.grid = (Grid)gridItem.Component;
51
this.adornerPanel = adornerPanel;
52
this.orientation = orientation;
53
this.displayUnitSelector=false;
54
this.unitSelector = new GridUnitSelector(this);
55
adornerPanel.Children.Add(unitSelector);
57
if (orientation == Orientation.Horizontal) {
58
this.Height = RailSize;
59
previewAdorner = new GridColumnSplitterAdorner(this, gridItem, null, null);
61
this.Width = RailSize;
62
previewAdorner = new GridRowSplitterAdorner(this, gridItem, null, null);
64
unitSelector.Orientation = orientation;
65
previewAdorner.IsPreview = true;
66
previewAdorner.IsHitTestVisible = false;
67
unitSelector.Visibility = Visibility.Hidden;
71
protected override void OnRender(DrawingContext drawingContext)
73
base.OnRender(drawingContext);
75
if (orientation == Orientation.Horizontal) {
76
Rect bgRect = new Rect(0, 0, grid.ActualWidth, RailSize);
77
drawingContext.DrawRectangle(bgBrush, null, bgRect);
79
DesignItemProperty colCollection = gridItem.Properties["ColumnDefinitions"];
80
foreach (var colItem in colCollection.CollectionElements) {
81
ColumnDefinition column = colItem.Component as ColumnDefinition;
82
if (column.ActualWidth < 0) continue;
83
GridLength len = (GridLength)column.GetValue(ColumnDefinition.WidthProperty);
85
FormattedText text = new FormattedText(GridLengthToText(len), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Sergio UI"), 10, Brushes.Black);
86
text.TextAlignment = TextAlignment.Center;
87
drawingContext.DrawText(text, new Point(column.Offset + column.ActualWidth / 2, 0));
90
Rect bgRect = new Rect(0, 0, RailSize, grid.ActualHeight);
91
drawingContext.DrawRectangle(bgBrush, null, bgRect);
93
DesignItemProperty rowCollection = gridItem.Properties["RowDefinitions"];
94
foreach (var rowItem in rowCollection.CollectionElements) {
95
RowDefinition row = rowItem.Component as RowDefinition;
96
if (row.ActualHeight < 0) continue;
97
GridLength len = (GridLength)row.GetValue(RowDefinition.HeightProperty);
99
FormattedText text = new FormattedText(GridLengthToText(len), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Sergio UI"), 10, Brushes.Black);
100
text.TextAlignment = TextAlignment.Center;
101
drawingContext.PushTransform(new RotateTransform(-90));
102
drawingContext.DrawText(text, new Point((row.Offset + row.ActualHeight / 2)*-1, 0));
103
drawingContext.Pop();
108
#region Handle mouse events to add a new row/column
109
protected override void OnMouseEnter(MouseEventArgs e)
111
base.OnMouseEnter(e);
112
this.Cursor = Cursors.Cross;
113
RelativePlacement rpUnitSelector = new RelativePlacement();
114
if (orientation == Orientation.Vertical)
116
double insertionPosition = e.GetPosition(this).Y;
117
RowDefinition current = grid.RowDefinitions
118
.FirstOrDefault(r => insertionPosition >= r.Offset &&
119
insertionPosition <= (r.Offset + r.ActualHeight));
122
DesignItem component = this.gridItem.Services.Component.GetDesignItem(current);
123
rpUnitSelector.XOffset = -(RailSize + RailDistance) * 2.75;
124
rpUnitSelector.WidthOffset = RailSize + RailDistance;
125
rpUnitSelector.WidthRelativeToContentWidth = 1;
126
rpUnitSelector.HeightOffset = 55;
127
rpUnitSelector.YOffset = current.Offset + current.ActualHeight / 2 - 25;
128
unitSelector.SelectedItem = component;
129
unitSelector.Unit = ((GridLength)component.Properties[RowDefinition.HeightProperty].ValueOnInstance).GridUnitType;
130
displayUnitSelector = true;
134
displayUnitSelector = false;
139
double insertionPosition = e.GetPosition(this).X;
140
ColumnDefinition current = grid.ColumnDefinitions
141
.FirstOrDefault(r => insertionPosition >= r.Offset &&
142
insertionPosition <= (r.Offset + r.ActualWidth));
145
DesignItem component = this.gridItem.Services.Component.GetDesignItem(current);
146
Debug.Assert(component != null);
147
rpUnitSelector.YOffset = -(RailSize + RailDistance) * 2.20;
148
rpUnitSelector.HeightOffset = RailSize + RailDistance;
149
rpUnitSelector.HeightRelativeToContentHeight = 1;
150
rpUnitSelector.WidthOffset = 75;
151
rpUnitSelector.XOffset = current.Offset + current.ActualWidth / 2 - 35;
152
unitSelector.SelectedItem = component;
153
unitSelector.Unit = ((GridLength)component.Properties[ColumnDefinition.WidthProperty].ValueOnInstance).GridUnitType;
154
displayUnitSelector = true;
158
displayUnitSelector = false;
161
if(displayUnitSelector)
162
unitSelector.Visibility = Visibility.Visible;
163
if(!adornerPanel.Children.Contains(previewAdorner))
164
adornerPanel.Children.Add(previewAdorner);
168
protected override void OnMouseMove(MouseEventArgs e)
171
RelativePlacement rp = new RelativePlacement();
172
RelativePlacement rpUnitSelector = new RelativePlacement();
173
if (orientation == Orientation.Vertical)
175
double insertionPosition = e.GetPosition(this).Y;
176
RowDefinition current = grid.RowDefinitions
177
.FirstOrDefault(r => insertionPosition >= r.Offset &&
178
insertionPosition <= (r.Offset + r.ActualHeight));
180
rp.XOffset = -(RailSize + RailDistance);
181
rp.WidthOffset = RailSize + RailDistance;
182
rp.WidthRelativeToContentWidth = 1;
183
rp.HeightOffset = SplitterWidth;
184
rp.YOffset = e.GetPosition(this).Y - SplitterWidth / 2;
187
DesignItem component = this.gridItem.Services.Component.GetDesignItem(current);
188
rpUnitSelector.XOffset = -(RailSize + RailDistance) * 2.75;
189
rpUnitSelector.WidthOffset = RailSize + RailDistance;
190
rpUnitSelector.WidthRelativeToContentWidth = 1;
191
rpUnitSelector.HeightOffset = 55;
192
rpUnitSelector.YOffset = current.Offset + current.ActualHeight / 2 - 25;
193
unitSelector.SelectedItem = component;
194
unitSelector.Unit = ((GridLength)component.Properties[RowDefinition.HeightProperty].ValueOnInstance).GridUnitType;
195
displayUnitSelector = true;
199
displayUnitSelector = false;
204
double insertionPosition = e.GetPosition(this).X;
205
ColumnDefinition current = grid.ColumnDefinitions
206
.FirstOrDefault(r => insertionPosition >= r.Offset &&
207
insertionPosition <= (r.Offset + r.ActualWidth));
209
rp.YOffset = -(RailSize + RailDistance);
210
rp.HeightOffset = RailSize + RailDistance;
211
rp.HeightRelativeToContentHeight = 1;
212
rp.WidthOffset = SplitterWidth;
213
rp.XOffset = e.GetPosition(this).X - SplitterWidth / 2;
217
DesignItem component = this.gridItem.Services.Component.GetDesignItem(current);
218
Debug.Assert(component != null);
219
rpUnitSelector.YOffset = -(RailSize + RailDistance) * 2.20;
220
rpUnitSelector.HeightOffset = RailSize + RailDistance;
221
rpUnitSelector.HeightRelativeToContentHeight = 1;
222
rpUnitSelector.WidthOffset = 75;
223
rpUnitSelector.XOffset = current.Offset + current.ActualWidth / 2 - 35;
224
unitSelector.SelectedItem = component;
225
unitSelector.Unit = ((GridLength)component.Properties[ColumnDefinition.WidthProperty].ValueOnInstance).GridUnitType;
226
displayUnitSelector = true;
230
displayUnitSelector = false;
233
AdornerPanel.SetPlacement(previewAdorner, rp);
234
if (displayUnitSelector)
235
AdornerPanel.SetPlacement(unitSelector, rpUnitSelector);
238
protected override void OnMouseLeave(MouseEventArgs e)
240
base.OnMouseLeave(e);
241
Mouse.UpdateCursor();
242
if (!unitSelector.IsMouseOver)
244
unitSelector.Visibility = Visibility.Hidden;
245
displayUnitSelector = false;
247
if(adornerPanel.Children.Contains(previewAdorner))
248
adornerPanel.Children.Remove(previewAdorner);
251
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
253
base.OnMouseLeftButtonDown(e);
256
adornerPanel.Children.Remove(previewAdorner);
257
if (orientation == Orientation.Vertical) {
258
double insertionPosition = e.GetPosition(this).Y;
259
DesignItemProperty rowCollection = gridItem.Properties["RowDefinitions"];
261
DesignItem currentRow = null;
263
using (ChangeGroup changeGroup = gridItem.OpenGroup("Split grid row")) {
264
if (rowCollection.CollectionElements.Count == 0) {
265
DesignItem firstRow = gridItem.Services.Component.RegisterComponentForDesigner(new RowDefinition());
266
rowCollection.CollectionElements.Add(firstRow);
267
grid.UpdateLayout(); // let WPF assign firstRow.ActualHeight
269
currentRow = firstRow;
271
RowDefinition current = grid.RowDefinitions
272
.FirstOrDefault(r => insertionPosition >= r.Offset &&
273
insertionPosition <= (r.Offset + r.ActualHeight));
275
currentRow = gridItem.Services.Component.GetDesignItem(current);
278
if (currentRow == null)
279
currentRow = gridItem.Services.Component.GetDesignItem(grid.RowDefinitions.Last());
281
unitSelector.SelectedItem = currentRow;
282
for (int i = 0; i < grid.RowDefinitions.Count; i++) {
283
RowDefinition row = grid.RowDefinitions[i];
284
if (row.Offset > insertionPosition) continue;
285
if (row.Offset + row.ActualHeight < insertionPosition) continue;
288
GridLength oldLength = (GridLength)row.GetValue(RowDefinition.HeightProperty);
289
GridLength newLength1, newLength2;
290
SplitLength(oldLength, insertionPosition - row.Offset, row.ActualHeight, out newLength1, out newLength2);
291
DesignItem newRowDefinition = gridItem.Services.Component.RegisterComponentForDesigner(new RowDefinition());
292
rowCollection.CollectionElements.Insert(i + 1, newRowDefinition);
293
rowCollection.CollectionElements[i].Properties[RowDefinition.HeightProperty].SetValue(newLength1);
294
newRowDefinition.Properties[RowDefinition.HeightProperty].SetValue(newLength2);
296
FixIndicesAfterSplit(i, Grid.RowProperty, Grid.RowSpanProperty,insertionPosition);
298
changeGroup.Commit();
303
double insertionPosition = e.GetPosition(this).X;
304
DesignItemProperty columnCollection = gridItem.Properties["ColumnDefinitions"];
306
DesignItem currentColumn = null;
308
using (ChangeGroup changeGroup = gridItem.OpenGroup("Split grid column")) {
309
if (columnCollection.CollectionElements.Count == 0) {
310
DesignItem firstColumn = gridItem.Services.Component.RegisterComponentForDesigner(new ColumnDefinition());
311
columnCollection.CollectionElements.Add(firstColumn);
312
grid.UpdateLayout(); // let WPF assign firstColumn.ActualWidth
314
currentColumn = firstColumn;
316
ColumnDefinition current = grid.ColumnDefinitions
317
.FirstOrDefault(r => insertionPosition >= r.Offset &&
318
insertionPosition <= (r.Offset + r.ActualWidth));
320
currentColumn = gridItem.Services.Component.GetDesignItem(current);
323
if (currentColumn == null)
324
currentColumn = gridItem.Services.Component.GetDesignItem(grid.ColumnDefinitions.Last());
326
unitSelector.SelectedItem = currentColumn;
327
for (int i = 0; i < grid.ColumnDefinitions.Count; i++) {
328
ColumnDefinition column = grid.ColumnDefinitions[i];
329
if (column.Offset > insertionPosition) continue;
330
if (column.Offset + column.ActualWidth < insertionPosition) continue;
333
GridLength oldLength = (GridLength)column.GetValue(ColumnDefinition.WidthProperty);
334
GridLength newLength1, newLength2;
335
SplitLength(oldLength, insertionPosition - column.Offset, column.ActualWidth, out newLength1, out newLength2);
336
DesignItem newColumnDefinition = gridItem.Services.Component.RegisterComponentForDesigner(new ColumnDefinition());
337
columnCollection.CollectionElements.Insert(i + 1, newColumnDefinition);
338
columnCollection.CollectionElements[i].Properties[ColumnDefinition.WidthProperty].SetValue(newLength1);
339
newColumnDefinition.Properties[ColumnDefinition.WidthProperty].SetValue(newLength2);
341
FixIndicesAfterSplit(i, Grid.ColumnProperty, Grid.ColumnSpanProperty,insertionPosition);
342
changeGroup.Commit();
351
private void FixIndicesAfterSplit(int splitIndex, DependencyProperty idxProperty, DependencyProperty spanProperty, double insertionPostion)
353
if (orientation == Orientation.Horizontal) {
354
// increment ColSpan of all controls in the split column, increment Column of all controls in later columns:
355
foreach (DesignItem child in gridItem.Properties["Children"].CollectionElements) {
356
Point topLeft = child.View.TranslatePoint(new Point(0, 0), grid);
357
var margin = (Thickness) child.Properties[FrameworkElement.MarginProperty].ValueOnInstance;
358
var start = (int) child.Properties.GetAttachedProperty(idxProperty).ValueOnInstance;
359
var span = (int) child.Properties.GetAttachedProperty(spanProperty).ValueOnInstance;
360
if (start <= splitIndex && splitIndex < start + span) {
361
var width = (double) child.Properties[FrameworkElement.ActualWidthProperty].ValueOnInstance;
362
if (insertionPostion >= topLeft.X + width) {
365
if (insertionPostion > topLeft.X)
366
child.Properties.GetAttachedProperty(spanProperty).SetValue(span + 1);
368
child.Properties.GetAttachedProperty(idxProperty).SetValue(start + 1);
369
margin.Left = topLeft.X - insertionPostion;
370
child.Properties[FrameworkElement.MarginProperty].SetValue(margin);
373
else if (start > splitIndex)
375
child.Properties.GetAttachedProperty(idxProperty).SetValue(start + 1);
381
foreach (DesignItem child in gridItem.Properties["Children"].CollectionElements)
383
Point topLeft = child.View.TranslatePoint(new Point(0, 0), grid);
384
var margin = (Thickness)child.Properties[FrameworkElement.MarginProperty].ValueOnInstance;
385
var start = (int)child.Properties.GetAttachedProperty(idxProperty).ValueOnInstance;
386
var span = (int)child.Properties.GetAttachedProperty(spanProperty).ValueOnInstance;
387
if (start <= splitIndex && splitIndex < start + span)
389
var height = (double)child.Properties[FrameworkElement.ActualHeightProperty].ValueOnInstance;
390
if (insertionPostion >= topLeft.Y + height)
392
if (insertionPostion > topLeft.Y)
393
child.Properties.GetAttachedProperty(spanProperty).SetValue(span + 1);
395
child.Properties.GetAttachedProperty(idxProperty).SetValue(start + 1);
396
margin.Top=topLeft.Y-insertionPostion;
397
child.Properties[FrameworkElement.MarginProperty].SetValue(margin);
400
else if (start > splitIndex)
402
child.Properties.GetAttachedProperty(idxProperty).SetValue(start + 1);
408
static void SplitLength(GridLength oldLength, double insertionPosition, double oldActualValue,
409
out GridLength newLength1, out GridLength newLength2)
411
if (oldLength.IsAuto) {
412
oldLength = new GridLength(oldActualValue);
414
double percentage = insertionPosition / oldActualValue;
415
newLength1 = new GridLength(oldLength.Value * percentage, oldLength.GridUnitType);
416
newLength2 = new GridLength(oldLength.Value - newLength1.Value, oldLength.GridUnitType);
420
string GridLengthToText(GridLength len)
422
switch (len.GridUnitType) {
423
case GridUnitType.Auto:
425
case GridUnitType.Star:
426
return len.Value == 1 ? "*" : Math.Round(len.Value, 2) + "*";
427
case GridUnitType.Pixel:
428
return Math.Round(len.Value, 2) + "px";
433
public void SetGridLengthUnit(GridUnitType unit)
435
DesignItem item = unitSelector.SelectedItem;
438
Debug.Assert(item != null);
440
if (orientation == Orientation.Vertical) {
441
SetGridLengthUnit(unit, item, RowDefinition.HeightProperty);
443
SetGridLengthUnit(unit, item, ColumnDefinition.WidthProperty);
449
void SetGridLengthUnit(GridUnitType unit, DesignItem item, DependencyProperty property)
451
DesignItemProperty itemProperty = item.Properties[property];
452
GridLength oldValue = (GridLength)itemProperty.ValueOnInstance;
453
GridLength value = GetNewGridLength(unit, oldValue);
455
if (value != oldValue) {
456
itemProperty.SetValue(value);
460
GridLength GetNewGridLength(GridUnitType unit, GridLength oldValue)
462
if (unit == GridUnitType.Auto) {
463
return GridLength.Auto;
465
return new GridLength(oldValue.Value, unit);
469
public abstract class GridSplitterAdorner : Control
471
public static readonly DependencyProperty IsPreviewProperty
472
= DependencyProperty.Register("IsPreview", typeof(bool), typeof(GridSplitterAdorner), new PropertyMetadata(SharedInstances.BoxedFalse));
474
protected readonly Grid grid;
475
protected readonly DesignItem gridItem;
476
protected readonly DesignItem firstRow, secondRow; // can also be columns
477
protected readonly GridRailAdorner rail;
479
internal GridSplitterAdorner(GridRailAdorner rail, DesignItem gridItem, DesignItem firstRow, DesignItem secondRow)
481
Debug.Assert(gridItem != null);
482
this.grid = (Grid)gridItem.Component;
483
this.gridItem = gridItem;
484
this.firstRow = firstRow;
485
this.secondRow = secondRow;
489
public bool IsPreview {
490
get { return (bool)GetValue(IsPreviewProperty); }
491
set { SetValue(IsPreviewProperty, SharedInstances.Box(value)); }
494
ChangeGroup activeChangeGroup;
495
double mouseStartPos;
498
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
501
if (CaptureMouse()) {
503
mouseStartPos = GetCoordinate(e.GetPosition(grid));
508
protected override void OnMouseMove(MouseEventArgs e)
511
double mousePos = GetCoordinate(e.GetPosition(grid));
512
if (activeChangeGroup == null) {
513
if (Math.Abs(mousePos - mouseStartPos)
514
>= GetCoordinate(new Point(SystemParameters.MinimumHorizontalDragDistance, SystemParameters.MinimumVerticalDragDistance))) {
515
activeChangeGroup = gridItem.OpenGroup("Change grid row/column size");
516
RememberOriginalSize();
519
if (activeChangeGroup != null) {
520
ChangeSize(mousePos - mouseStartPos);
525
protected GridLength original1, original2;
526
protected double originalPixelSize1, originalPixelSize2;
528
protected abstract double GetCoordinate(Point point);
529
protected abstract void RememberOriginalSize();
530
protected abstract DependencyProperty RowColumnSizeProperty { get; }
532
void ChangeSize(double delta)
534
// delta = difference in pixels
536
if (delta < -originalPixelSize1) delta = -originalPixelSize1;
537
if (delta > originalPixelSize2) delta = originalPixelSize2;
539
// replace Auto lengths with absolute lengths if necessary
540
if (original1.IsAuto) original1 = new GridLength(originalPixelSize1);
541
if (original2.IsAuto) original2 = new GridLength(originalPixelSize2);
544
if (original1.IsStar && originalPixelSize1 > 0)
545
new1 = new GridLength(original1.Value * (originalPixelSize1 + delta) / originalPixelSize1, GridUnitType.Star);
547
new1 = new GridLength(originalPixelSize1 + delta);
549
if (original2.IsStar && originalPixelSize2 > 0)
550
new2 = new GridLength(original2.Value * (originalPixelSize2 - delta) / originalPixelSize2, GridUnitType.Star);
552
new2 = new GridLength(originalPixelSize2 - delta);
553
firstRow.Properties[RowColumnSizeProperty].SetValue(new1);
554
secondRow.Properties[RowColumnSizeProperty].SetValue(new2);
555
UIElement e = ((UIElement)VisualTreeHelper.GetParent(this));
556
e.InvalidateArrange();
557
rail.InvalidateVisual();
560
protected override void OnMouseUp(MouseButtonEventArgs e)
562
if (activeChangeGroup != null) {
563
activeChangeGroup.Commit();
564
activeChangeGroup = null;
569
protected override void OnLostMouseCapture(MouseEventArgs e)
574
protected override void OnKeyDown(KeyEventArgs e)
576
if (e.Key == Key.Escape) {
582
protected void Stop()
584
ReleaseMouseCapture();
586
if (activeChangeGroup != null) {
587
activeChangeGroup.Abort();
588
activeChangeGroup = null;
593
public class GridRowSplitterAdorner : GridSplitterAdorner
595
static GridRowSplitterAdorner()
597
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridRowSplitterAdorner), new FrameworkPropertyMetadata(typeof(GridRowSplitterAdorner)));
598
CursorProperty.OverrideMetadata(typeof(GridRowSplitterAdorner), new FrameworkPropertyMetadata(Cursors.SizeNS));
601
internal GridRowSplitterAdorner(GridRailAdorner rail, DesignItem gridItem, DesignItem firstRow, DesignItem secondRow)
602
: base(rail, gridItem, firstRow, secondRow)
606
protected override double GetCoordinate(Point point)
611
protected override void RememberOriginalSize()
613
RowDefinition r1 = (RowDefinition)firstRow.Component;
614
RowDefinition r2 = (RowDefinition)secondRow.Component;
615
original1 = (GridLength)r1.GetValue(RowDefinition.HeightProperty);
616
original2 = (GridLength)r2.GetValue(RowDefinition.HeightProperty);
617
originalPixelSize1 = r1.ActualHeight;
618
originalPixelSize2 = r2.ActualHeight;
621
protected override DependencyProperty RowColumnSizeProperty {
622
get { return RowDefinition.HeightProperty; }
626
public sealed class GridColumnSplitterAdorner : GridSplitterAdorner
628
static GridColumnSplitterAdorner()
630
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridColumnSplitterAdorner), new FrameworkPropertyMetadata(typeof(GridColumnSplitterAdorner)));
631
CursorProperty.OverrideMetadata(typeof(GridColumnSplitterAdorner), new FrameworkPropertyMetadata(Cursors.SizeWE));
634
internal GridColumnSplitterAdorner(GridRailAdorner rail, DesignItem gridItem, DesignItem firstRow, DesignItem secondRow)
635
: base(rail, gridItem, firstRow, secondRow)
639
protected override double GetCoordinate(Point point)
644
protected override void RememberOriginalSize()
646
ColumnDefinition r1 = (ColumnDefinition)firstRow.Component;
647
ColumnDefinition r2 = (ColumnDefinition)secondRow.Component;
648
original1 = (GridLength)r1.GetValue(ColumnDefinition.WidthProperty);
649
original2 = (GridLength)r2.GetValue(ColumnDefinition.WidthProperty);
650
originalPixelSize1 = r1.ActualWidth;
651
originalPixelSize2 = r2.ActualWidth;
654
protected override DependencyProperty RowColumnSizeProperty {
655
get { return ColumnDefinition.WidthProperty; }