Silverlight智能表单(1)关于控件拖动

前几天闲来无事就在家做sl的智能表单,因为技术有限,各种架构没能设计好,于是-------大家都知道,我拿出自己算是能够称的上功能的东西给大家分享一下。

1.控件在画布上拖动和大小设置。

2.控件从工具箱拖到画布。

3.生成XML。

今天就只写第一个在画布上拖动和设置大小,当时我想的是只做一个拖动的控件(占时叫SizeCtr),然后点击哪个控件,SizeCtr就放到哪个控件上面。

先展示下  SizeCtr  和  运行的效果:

sizectr2

 

这是两个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;
            }

今天就写这么多,以后我会将我做的未完成的智能表单拿出来供大家分享,虽然个人技术能力有限,在设计方面缺陷太大。仅仅供大家一个思考的方法,如果能对你有帮助,拿去用哈哈。。。。

你可能感兴趣的:(silverlight)