我找到Article来Controls
调整Canvas
,但没有“装饰者”。
我尝试在我的代码中使用它,但是有很多不同之处。
Contents
Canvas
Window
Controls
使用这部分代码动态创建Controls
:
public void createNewModuleContainer()
{
//Parts
Grid moduleGrid = new Grid();
UserControl ucModule = new UserControl();
Grid editGrid = new Grid();
Rectangle whiteBody = new Rectangle();
ComboBox cbModules = new ComboBox();
Button btnDeleteModule = new Button();
//Hierarchie
modulesBody.Children.Add(moduleGrid);
moduleGrid.Children.Add(ucModule);
moduleGrid.Children.Add(editGrid);
editGrid.Children.Add(whiteBody);
editGrid.Children.Add(cbModules);
editGrid.Children.Add(btnDeleteModule);
//moduleGrid
moduleGrid.Width = 100;
moduleGrid.Height = 50;
Canvas.SetLeft(moduleGrid, 100);
Canvas.SetTop(moduleGrid, 100);
//ucModule
ucModule.HorizontalAlignment = HorizontalAlignment.Stretch;
ucModule.VerticalAlignment = VerticalAlignment.Stretch;
ucModulList.Add(ucModule);
//editgrid
editGrid.HorizontalAlignment = HorizontalAlignment.Stretch;
editGrid.VerticalAlignment = VerticalAlignment.Stretch;
editGrid.Margin = new Thickness(0, 0, 0, 0);
editGrid.Background = new SolidColorBrush(Colors.Transparent);
editGrid.MouseLeftButtonDown += moduleGrid_MouseDown;
editGrid.MouseLeftButtonUp += moduleGrid_MouseUp;
editGrid.MouseMove += moduleGrid_MouseMove;
//whitebody
whiteBody.Fill = new SolidColorBrush(Colors.White);
whiteBody.Opacity = 0.5;
whiteBody.HorizontalAlignment = HorizontalAlignment.Stretch;
whiteBody.VerticalAlignment = VerticalAlignment.Stretch;
//cbModules
cbModules.Cursor = Cursors.Hand;
cbModules.Width = 20;
cbModules.HorizontalAlignment = HorizontalAlignment.Right;
cbModules.VerticalAlignment = VerticalAlignment.Top;
cbModules.Height = 20;
cbModules.Margin = new Thickness(0, 0, 0, 0);
cbModules.SelectionChanged += CbModule1_SelectionChanged;
fillCheckboxes(cbModules);
//btnDelete
btnDeleteModule.Cursor = Cursors.Hand;
btnDeleteModule.Width = 20;
btnDeleteModule.Height = 20;
btnDeleteModule.HorizontalAlignment = HorizontalAlignment.Left;
btnDeleteModule.VerticalAlignment = VerticalAlignment.Top;
btnDeleteModule.Margin = new Thickness(0, 0, 0, 0);
BitmapImage image = new BitmapImage(new Uri("pack://application:,,,/Timestamp;component/View/UserControls/Images/close.png"));
btnDeleteModule.Background = new ImageBrush(image);
btnDeleteModule.Visibility = Visibility.Visible;
btnDeleteModule.Click += DeleteModuleButtonClicked;
}
我编辑了本文中的代码,如下所示:
// The part of the grid the mouse is over.
private enum HitType
{
None, Body, UL, UR, LR, LL, L, R, T, B
};
// True if a drag is in progress.
private bool DragInProgress = false;
// The drag's last point.
private Point LastPoint;
// The part of the grid under the mouse.
HitType MouseHitType = HitType.None;
// Return a HitType value to indicate what is at the point.
private HitType SetHitType(Grid moduleGrid, Point point)
{
;
double left = Canvas.GetLeft(moduleGrid);
double top = Canvas.GetTop(moduleGrid);
double right = left + moduleGrid.ActualWidth;
double bottom = top + moduleGrid.ActualHeight;
if (point.X < left) return HitType.None;
if (point.X > right) return HitType.None;
if (point.Y < top) return HitType.None;
if (point.Y > bottom) return HitType.None;
const double GAP = 3;
if (point.X - left < GAP)
{
// Left edge.
if (point.Y - top < GAP) return HitType.UL;
if (bottom - point.Y < GAP) return HitType.LL;
return HitType.L;
}
if (right - point.X < GAP)
{
// Right edge.
if (point.Y - top < GAP) return HitType.UR;
if (bottom - point.Y < GAP) return HitType.LR;
return HitType.R;
}
if (point.Y - top < GAP) return HitType.T;
if (bottom - point.Y < GAP) return HitType.B;
return HitType.Body;
}
private void SetMouseCursor()
{
// See what cursor we should display.
Cursor desired_cursor = Cursors.Arrow;
switch (MouseHitType)
{
case HitType.None:
desired_cursor = Cursors.Arrow;
break;
case HitType.Body:
desired_cursor = Cursors.SizeAll;
break;
case HitType.UL:
case HitType.LR:
desired_cursor = Cursors.SizeNWSE;
break;
case HitType.LL:
case HitType.UR:
desired_cursor = Cursors.SizeNESW;
break;
case HitType.T:
case HitType.B:
desired_cursor = Cursors.SizeNS;
break;
case HitType.L:
case HitType.R:
desired_cursor = Cursors.SizeWE;
break;
}
// Display the desired cursor.
if (Cursor != desired_cursor) Cursor = desired_cursor;
}
// Start dragging.
private void moduleGrid_MouseDown(object sender, MouseButtonEventArgs e)
{
if (!DragInProgress)
{
Console.WriteLine("Dragging Module");
var element = sender as Grid;
Grid parentGrid = element.Parent as Grid;
selectedGrid = parentGrid;
MouseHitType = SetHitType(selectedGrid, Mouse.GetPosition(modulesBody));
SetMouseCursor();
if (MouseHitType == HitType.None) return;
LastPoint = Mouse.GetPosition(modulesBody);
DragInProgress = true;
}
else
{
DragInProgress = false;
}
}
// If a drag is in progress, continue the drag.
// Otherwise display the correct cursor.
private void moduleGrid_MouseMove(object sender, MouseEventArgs e)
{
var element = sender as Grid;
Grid parentGrid = element.Parent as Grid;
if (!DragInProgress)
{
MouseHitType = SetHitType(parentGrid, Mouse.GetPosition(modulesBody));
SetMouseCursor();
}
else
{
// See how much the mouse has moved.
Point point = Mouse.GetPosition(modulesBody);
double offset_x = point.X - LastPoint.X;
double offset_y = point.Y - LastPoint.Y;
// Get the grid's current position.
double new_x = Canvas.GetLeft(selectedGrid);
double new_y = Canvas.GetTop(selectedGrid);
double new_width = selectedGrid.Width;
double new_height = selectedGrid.Height;
// Update the grid.
switch (MouseHitType)
{
case HitType.Body:
new_x += offset_x;
new_y += offset_y;
break;
case HitType.UL:
new_x += offset_x;
new_y += offset_y;
new_width -= offset_x;
new_height -= offset_y;
break;
case HitType.UR:
new_y += offset_y;
new_width += offset_x;
new_height -= offset_y;
break;
case HitType.LR:
new_width += offset_x;
new_height += offset_y;
break;
case HitType.LL:
new_x += offset_x;
new_width -= offset_x;
new_height += offset_y;
break;
case HitType.L:
new_x += offset_x;
new_width -= offset_x;
break;
case HitType.R:
new_width += offset_x;
break;
case HitType.B:
new_height += offset_y;
break;
case HitType.T:
new_y += offset_y;
new_height -= offset_y;
break;
}
// Don't use negative width or height.
if ((new_width > 0) && (new_height > 0))
{
// Update the Grid
Canvas.SetLeft(selectedGrid, new_x);
Canvas.SetTop(selectedGrid, new_y);
selectedGrid.Width = new_width;
selectedGrid.Height = new_height;
// Save the mouse's new location.
LastPoint = point;
}
}
}
// Stop dragging.
private void moduleGrid_MouseUp(object sender, MouseButtonEventArgs e)
{
DragInProgress = false;
}
这适合我,但它的行为非常疯狂:
鼠标向上不会释放draggin,这就是为什么我将if指令添加到鼠标按下事件。另外,增加Control
的大小非常困难,你必须将鼠标移动得很慢
谁在那里看到问题?