前几天闲来无事就在家做sl的智能表单,因为技术有限,各种架构没能设计好,于是-------大家都知道,我拿出自己算是能够称的上功能的东西给大家分享一下。
1.控件在画布上拖动和大小设置。
2.控件从工具箱拖到画布。
3.生成XML。
今天就只写第一个在画布上拖动和设置大小,当时我想的是只做一个拖动的控件(占时叫SizeCtr),然后点击哪个控件,SizeCtr就放到哪个控件上面。
先展示下 SizeCtr 和 运行的效果:
这是两个Button,其中一个被选中。SizeCtr在边上有8个小锚点(Rectangle),还有中间一个大的框框(Border)
展示下Xaml
<UserControl x:Class="ITLight.Controls.SizeCtr"
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"
mc:Ignorable="d"
d:DesignHeight="78" d:DesignWidth="216">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.Resources>
<Style TargetType="Rectangle">
<Setter Property="Height" Value="4" />
<Setter Property="Width" Value="4" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Stroke" Value="Black" />
<Setter Property="StrokeThickness" Value="1" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="4" />
<RowDefinition Height="Auto" />
<RowDefinition Height="4" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="4" />
</Grid.ColumnDefinitions>
<Border Name="SizeBorder" Grid.Row="1" Grid.Column="1" BorderBrush="Black" BorderThickness="1" Background="#1000" Cursor="Hand" />
<Rectangle Grid.Row="0" Grid.Column="0" />
<Rectangle Grid.Row="0" Grid.Column="1"/>
<Rectangle Grid.Row="0" Grid.Column="2" />
<Rectangle Grid.Row="1" Grid.Column="0" />
<Rectangle Grid.Row="1" Grid.Column="2" />
<Rectangle Grid.Row="2" Grid.Column="0" />
<Rectangle Grid.Row="2" Grid.Column="1" />
<Rectangle Grid.Row="2" Grid.Column="2" />
</Grid>
</UserControl>
还有CS文件:
public partial class SizeCtr : UserControl
{
public SizeCtr()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(OnSizeCtrLoaded);
}
private void OnSizeCtrLoaded(object sender, RoutedEventArgs e)
{
this.Loaded -= new RoutedEventHandler(OnSizeCtrLoaded);
UIElementCollection rects = LayoutRoot.Children;
foreach (var item in rects)
{
if (item is Rectangle)
{
Rectangle rect = item as Rectangle;
rect.MouseLeftButtonDown += new MouseButtonEventHandler(OnRectMouseLeftButtonDown);
rect.MouseLeftButtonUp += new MouseButtonEventHandler(OnRectMouseLeftButtonUp);
rect.MouseMove += new MouseEventHandler(OnRectMouseMove);
int row = Grid.GetRow(rect);
int col = Grid.GetColumn(rect);
if (row == 1)
{
rect.Cursor = Cursors.SizeWE;
}
else if (col == 1)
{
rect.Cursor = Cursors.SizeNS;
}
else if (row == col)
{
rect.Cursor = Cursors.SizeNWSE;
}
else
{
rect.Cursor = Cursors.SizeNESW;
}
}
SizeBorder.MouseLeftButtonDown += new MouseButtonEventHandler(SizeBorder_MouseLeftButtonDown);
SizeBorder.MouseLeftButtonUp += new MouseButtonEventHandler(SizeBorder_MouseLeftButtonUp);
SizeBorder.MouseMove += new MouseEventHandler(SizeBorder_MouseMove);
}
}
private FrameworkElement m_Target;
public FrameworkElement Target
{
get { return m_Target; }
set
{
if (m_Target != value)
{
m_Target = value;
if (value != null)
{
SizeBorder.Height = m_Target.Height;
SizeBorder.Width = m_Target.Width;
Canvas.SetLeft(this as FrameworkElement, Canvas.GetLeft(m_Target) - 4);
Canvas.SetTop(this as FrameworkElement, Canvas.GetTop(m_Target) - 4);
this.Visibility = System.Windows.Visibility.Visible;
}
else
{
this.Visibility = System.Windows.Visibility.Collapsed;
}
}
}
}
#region Move
bool canMove;
private void SizeBorder_MouseMove(object sender, MouseEventArgs e)
{
if (canMove)
{
Point newPosition = e.GetPosition(null);
double height = newPosition.Y - mousePosition.Y;
double width = newPosition.X - mousePosition.X;
Canvas.SetTop(this as FrameworkElement, Canvas.GetTop(this as FrameworkElement) + height);
Canvas.SetLeft(this as FrameworkElement, Canvas.GetLeft(this as FrameworkElement) + width);
if (m_Target != null)
{
Canvas.SetTop(m_Target, Canvas.GetTop(m_Target) + height);
Canvas.SetLeft(m_Target, Canvas.GetLeft(m_Target) + width);
}
mousePosition = newPosition;
}
}
private void SizeBorder_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
canMove = false;
(sender as FrameworkElement).ReleaseMouseCapture();
//this.ReleaseMouseCapture();
}
private void SizeBorder_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
canMove = true;
mousePosition = e.GetPosition(null);
(sender as FrameworkElement).CaptureMouse();
//this.ReleaseMouseCapture();
}
#endregion
#region Size
private bool canSize;
Point mousePosition;
private void OnRectMouseMove(object sender, MouseEventArgs e)
{
if (canSize)
{
Rectangle rect = sender as Rectangle;
int row = Grid.GetRow(rect);
int col = Grid.GetColumn(rect);
Point newPoint = e.GetPosition(null);
double width = (newPoint.X - mousePosition.X) * (col - 1);
double height = (newPoint.Y - mousePosition.Y) * (row - 1);
SizeBorder.Width += width;
SizeBorder.Height += height;
if (m_Target != null)
{
m_Target.Height += height;
m_Target.Width += width;
}
if (row < 1)
{
Canvas.SetTop(this as FrameworkElement, Canvas.GetTop(this as FrameworkElement) - height);
if (m_Target != null)
{
Canvas.SetTop(m_Target, Canvas.GetTop(m_Target) - height);
}
}
if (col < 1)
{
Canvas.SetLeft(this as FrameworkElement, Canvas.GetLeft(this as FrameworkElement) - width);
if (m_Target != null)
{
Canvas.SetLeft(m_Target, Canvas.GetLeft(m_Target) - width);
}
}
mousePosition = newPoint;
}
}
private void OnRectMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
canSize = false;
(sender as Rectangle).ReleaseMouseCapture();
//this.ReleaseMouseCapture();
}
private void OnRectMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
canSize = true;
mousePosition = e.GetPosition(null);
(sender as Rectangle).CaptureMouse();
//this.CaptureMouse();
}
#endregion
}
代码几乎仔细看看都能看明白有几点说明:
1.在设置锚点的鼠标状态时以及改变大小时稍微动了点脑子很easy。。
2.Target属性就是设置当前的选中控件,如果是null的话就将他隐藏掉。
3.一点重要的说明,控件的容器必须是Canvas,SizeCtr也必须是画布Canvas的成员之一而且是最后一个,不然就不能保证在最上面。
4.中间的Border也设置了颜色,透明度设为最低,如果设成不透明的。。。。自己试试(呵呵)。
5.Canvas上要注册的事件MouseLeftButtonUp以及GotFocus,注册一个的话可能不能实现所有的控件的选中。
6.这点说明下,ComboBox选中时会下拉,所以加一句这个,让他不下拉。(哦,忘记了Xaml中能不能设置IsDropDownOpen ,如果能设直接设置成false就可以了,我不测试了。)
if (e.OriginalSource is ComboBox)
{
(e.OriginalSource as ComboBox).IsDropDownOpen = false;
}
今天就写这么多,以后我会将我做的未完成的智能表单拿出来供大家分享,虽然个人技术能力有限,在设计方面缺陷太大。仅仅供大家一个思考的方法,如果能对你有帮助,拿去用哈哈。。。。