天天看点

WPF中GDI+图形图像的绘制:(八)位置坐标和宽高与控件绑定展示

上一节展示了鼠标拖动改变图片位置和大小,下面介绍下鼠标拖动和控件之间的双向绑定展示,效果如下:

WPF中GDI+图形图像的绘制:(八)位置坐标和宽高与控件绑定展示

实现步骤:

1、MyImage自定义控件与博文WPF中GDI+图形图像的绘制:(七)绘制图像——鼠标拖动改变位置和大小中一致

2、主窗体xaml

<Window x:Class="DrawDemo.MainWindow"
        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"
        xmlns:local="clr-namespace:DrawDemo"
        xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
        xmlns:winForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
        Title="控件绑定" Height="768" Width="1280">
    <Grid Background="#f0f0f0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"></ColumnDefinition>
            <ColumnDefinition ></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="380"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Canvas x:Name="mainCanvas" Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Background="White" Width="960" Height="720" Margin="10,5,0,0"
                HorizontalAlignment="Left" VerticalAlignment="Top" ClipToBounds="True"
                MouseLeftButtonDown="mainCanvas_MouseLeftButtonDown" MouseLeftButtonUp="mainCanvas_MouseLeftButtonUp" MouseMove="mainCanvas_MouseMove">
        </Canvas>
        <GroupBox Grid.Row="0" Grid.Column="1" Margin="10" Header="控件绑定">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="50"></RowDefinition>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="80"></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Label Grid.Row="0" Grid.Column="0" Content="选择图片" VerticalAlignment="Center" HorizontalAlignment="Right"></Label>
                <Button x:Name="btnChooseImg" Grid.Row="0" Grid.Column="1" Content="选择" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="80" Margin="10,0,0,0" Click="btnChooseImg_Click"></Button>
                <Label Grid.Row="1" Grid.Column="0" Content="X坐标" VerticalAlignment="Center" HorizontalAlignment="Right"></Label>
                <wfi:WindowsFormsHost Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="80" Margin="10,0,0,0">
                    <winForms:NumericUpDown x:Name="locationX" Minimum="0" Maximum="9999" ValueChanged="LocationX_ValueChanged"></winForms:NumericUpDown>
                </wfi:WindowsFormsHost>
                <Label Grid.Row="2" Grid.Column="0" Content="Y坐标" VerticalAlignment="Center" HorizontalAlignment="Right"></Label>
                <wfi:WindowsFormsHost Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="80" Margin="10,0,0,0">
                    <winForms:NumericUpDown x:Name="locationY" Minimum="0" Maximum="9999" ValueChanged="LocationY_ValueChanged"></winForms:NumericUpDown>
                </wfi:WindowsFormsHost>
                <Label Grid.Row="3" Grid.Column="0" Content="宽" VerticalAlignment="Center" HorizontalAlignment="Right"></Label>
                <wfi:WindowsFormsHost Grid.Row="3" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="80" Margin="10,0,0,0">
                    <winForms:NumericUpDown x:Name="imgWidth" Minimum="0" Maximum="9999" ValueChanged="ImgWidth_ValueChanged"></winForms:NumericUpDown>
                </wfi:WindowsFormsHost>
                <Label Grid.Row="4" Grid.Column="0" Content="高" VerticalAlignment="Center" HorizontalAlignment="Right"></Label>
                <wfi:WindowsFormsHost Grid.Row="4" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="80" Margin="10,0,0,0">
                    <winForms:NumericUpDown x:Name="imgHeight" Minimum="0" Maximum="9999" ValueChanged="ImgHeight_ValueChanged"></winForms:NumericUpDown>
                </wfi:WindowsFormsHost>
            </Grid>
        </GroupBox>
    </Grid>
</Window>
           

3、鼠标按下抬起、拖动改变图片位置和大小的逻辑同上节一致,不同的是加入了和NumericUpDown之间的双向绑定展示,逻辑交互如下:

/// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private Point pBefore = new Point();//鼠标点击前坐标
        private Point eBefore = new Point();//图片移动前坐标     
        private double wBefore;//图片改变大小前宽
        private double hBefore;//图片改变大小前高
        private int minImgValue = 10;//图片最小宽高
        private bool IsCanMove = false;//是否可以移动

        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 选择图片
        /// </summary>
        private void btnChooseImg_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "选择图片";
            openFileDialog.Filter = "图片(*.jpg,*.png,*.bmp)|*.jpg;*.png;*.bmp"; ;
            openFileDialog.FileName = string.Empty;
            openFileDialog.Multiselect = false;
            openFileDialog.InitialDirectory = @"C:\Image";
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                BitmapImage bi = ImageHelper.LoadBitmapImageByPath(openFileDialog.FileName);
                if (bi != null)
                {
                    MyImage imgPic = new MyImage();
                    imgPic.Source = bi;
                    imgPic.Width = bi.PixelWidth;
                    imgPic.Height = bi.PixelHeight;
                    this.mainCanvas.Children.Add(imgPic);
                    Canvas.SetLeft(imgPic, (this.mainCanvas.ActualWidth - bi.PixelWidth) / 2);
                    Canvas.SetTop(imgPic, (this.mainCanvas.ActualHeight - bi.PixelHeight) / 2);
                }
            }
        }

        /// <summary>
        /// 鼠标按下
        /// </summary>
        private void mainCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.OriginalSource.GetType() == typeof(MyImage))
            {
                MyImage img = (MyImage)e.OriginalSource;
                //获取点击前鼠标坐标
                this.pBefore = e.GetPosition(this.mainCanvas);
                //获取点击图片的坐标和位置
                this.eBefore = new Point(Canvas.GetLeft(img), Canvas.GetTop(img));
                this.wBefore = img.Width;
                this.hBefore = img.Height;
                //设置为可移动
                IsCanMove = true;
                //鼠标捕获此图片
                img.CaptureMouse();
                img.IsSelect = true;
                img.InvalidateVisual();
                //展示XY坐标
                ShowXY(img);
                //展示宽高
                ShowWH(img);
                SetOtherUnSelect(img);
                //改变鼠标样式
                this.Cursor = System.Windows.Input.Cursors.SizeAll;
            }
            else
            {
                SetOtherUnSelect();
            }
        }
        /// <summary>
        /// 鼠标抬起
        /// </summary>
        private void mainCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (e.OriginalSource.GetType() == typeof(MyImage))
            {
                MyImage img = (MyImage)e.OriginalSource;
                //设置为不可移动
                IsCanMove = false;
                //鼠标释放此图片
                img.ReleaseMouseCapture();
                img.InvalidateVisual();
                this.Cursor = System.Windows.Input.Cursors.Arrow;
            }
        }
        /// <summary>
        /// 鼠标移动
        /// </summary>
        private void mainCanvas_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (!IsCanMove)
                return;

            if (e.OriginalSource != null && e.LeftButton == MouseButtonState.Pressed)
            {
                if (e.OriginalSource.GetType() == typeof(MyImage))
                {
                    MyImage img = (MyImage)e.OriginalSource;

                    if (IsCanMove && img != null)
                    {
                        MoveChange(e, img.changeType);
                    }
                }
                else
                {
                    base.OnMouseMove(e);
                }
            }
            else
                this.Cursor = System.Windows.Input.Cursors.Arrow;
        }
        /// <summary>
        /// 移动改变坐标或大小
        /// </summary>
        private void MoveChange(System.Windows.Input.MouseEventArgs e, ChangeType changeType)
        {
            try
            {
                switch (changeType)
                {
                    case ChangeType.ChangeLeftTop:
                        setLTvp(e);
                        break;
                    case ChangeType.ChangeRightTop:
                        setRTvp(e);
                        break;
                    case ChangeType.ChangeRightBottom:
                        setRBvp(e);
                        break;
                    case ChangeType.ChangeLeftBottom:
                        setLBvp(e);
                        break;
                    case ChangeType.Move:
                        MyImage img = (MyImage)e.OriginalSource;
                        if (img != null)
                            MoveImage(e);
                        break;
                }
            }
            catch (Exception ex)
            {
            }
        }
        /// <summary>
		/// 移动对象
		/// </summary>
		public void MoveImage(System.Windows.Input.MouseEventArgs e)
        {
            MyImage img = (MyImage)e.OriginalSource;
            //获取鼠标移动中的坐标
            Point p = e.GetPosition(this.mainCanvas);
            //计算拖拽距离
            double dragx = p.X - pBefore.X;
            double dragy = p.Y - pBefore.Y;
            //当拖拽距离大于一定范围时改变控件位置
            if(Math.Abs(dragx) > 5 || Math.Abs(dragy) > 5)
            {
                Canvas.SetLeft(img, eBefore.X + dragx);
                Canvas.SetTop(img, eBefore.Y + dragy);
                img.InvalidateVisual();

                ShowXY(img);
            }
        }
        /// <summary>
        /// 左上角拖动
        /// </summary>
        public void setLTvp(System.Windows.Input.MouseEventArgs e)
        {
            //获取鼠标移动中的坐标
            Point p = e.GetPosition(this);
            if (e.OriginalSource.GetType() == typeof(MyImage))
            {
                MyImage img = (MyImage)e.OriginalSource;
                double changeX = p.X - pBefore.X;
                double changeY = p.Y - pBefore.Y;

                if ((wBefore - changeX) > minImgValue)
                {
                    Canvas.SetLeft(img, eBefore.X + changeX);
                    img.Width = wBefore - changeX;
                }
                else
                {
                    img.Width = minImgValue;
                }

                if ((hBefore - changeY) > minImgValue)
                {
                    Canvas.SetTop(img, eBefore.Y + changeY);
                    img.Height = hBefore - changeY;
                }
                else
                {
                    img.Height = minImgValue;
                }
                img.InvalidateVisual();

                ShowXY(img);
                ShowWH(img);
            }
        }
        /// <summary>
        /// 右上角拖动
        /// </summary>
        public void setRTvp(System.Windows.Input.MouseEventArgs e)
        {
            //获取鼠标移动中的坐标
            Point p = e.GetPosition(this);
            if (e.OriginalSource.GetType() == typeof(MyImage))
            {
                MyImage img = (MyImage)e.OriginalSource;
                double changeX = p.X - pBefore.X;
                double changeY = p.Y - pBefore.Y;

                img.Width = (wBefore + changeX) > minImgValue ? wBefore + changeX : minImgValue;

                if ((hBefore - changeY) > minImgValue)
                {
                    Canvas.SetTop(img, eBefore.Y + changeY);
                    img.Height = hBefore - changeY;
                }
                else
                {
                    img.Height = minImgValue;
                }
                img.InvalidateVisual();

                ShowXY(img);
                ShowWH(img);
            }
        }
        /// <summary>
        /// 左下角拖动
        /// </summary>
        public void setLBvp(System.Windows.Input.MouseEventArgs e)
        {
            //获取鼠标移动中的坐标
            Point p = e.GetPosition(this);
            if (e.OriginalSource.GetType() == typeof(MyImage))
            {
                MyImage img = (MyImage)e.OriginalSource;
                double changeX = p.X - pBefore.X;
                double changeY = p.Y - pBefore.Y;

                if ((wBefore - changeX) > minImgValue)
                {
                    Canvas.SetLeft(img, eBefore.X + changeX);
                    img.Width = wBefore - changeX;
                }
                else
                {
                    img.Width = minImgValue;
                }
                img.Height = (hBefore + changeY) > minImgValue ? hBefore + changeY : minImgValue;
                img.InvalidateVisual();

                ShowXY(img);
                ShowWH(img);
            }
        }
        /// <summary>
        /// 右下角拖动
        /// </summary>
        public void setRBvp(System.Windows.Input.MouseEventArgs e)
        {
            //获取鼠标移动中的坐标
            Point p = e.GetPosition(this);
            if (e.OriginalSource.GetType() == typeof(MyImage))
            {
                MyImage img = (MyImage)e.OriginalSource;
                double changeX = p.X - pBefore.X;
                double changeY = p.Y - pBefore.Y;
                img.Width = (wBefore + changeX) > minImgValue ? wBefore + changeX : minImgValue;
                img.Height = (hBefore + changeY) > minImgValue ? hBefore + changeY : minImgValue;
                img.InvalidateVisual();

                ShowWH(img);
            }
        }
        /// <summary>
        /// 设置其他为未选择状态
        /// </summary>
        public void SetOtherUnSelect(object myImage = null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(this.mainCanvas); i++)
            {
                if (VisualTreeHelper.GetChild(this.mainCanvas, i).GetType() == typeof(MyImage))
                {
                    MyImage child = (MyImage)VisualTreeHelper.GetChild(this.mainCanvas, i);
                    if (myImage == null)
                    {
                        child.IsSelect = false;
                        child.InvalidateVisual();
                    }
                    else if (myImage != child)
                    {
                        if (child.IsSelect)
                        {
                            child.IsSelect = false;
                            child.InvalidateVisual();
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 展示XY坐标
        /// </summary>
        private void ShowXY(MyImage img)
        {
            this.locationX.Value = Convert.ToDecimal(Canvas.GetLeft(img));
            this.locationY.Value = Convert.ToDecimal(Canvas.GetTop(img));
        }
        /// <summary>
        /// 展示img宽高
        /// </summary>
        private void ShowWH(MyImage img)
        {
            this.imgWidth.Value = Convert.ToDecimal(img.Width);
            this.imgHeight.Value = Convert.ToDecimal(img.Height);
        }

        /// <summary>
        /// X坐标改变事件
        /// </summary>
        private void LocationX_ValueChanged(object sender, EventArgs e)
        {
            if (IsCanMove)
                return;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(this.mainCanvas); i++)
            {
                if (VisualTreeHelper.GetChild(this.mainCanvas, i).GetType() == typeof(MyImage))
                {
                    MyImage child = (MyImage)VisualTreeHelper.GetChild(this.mainCanvas, i);
                    if (child.IsSelect)
                    {
                        Canvas.SetLeft(child, Convert.ToDouble(this.locationX.Value));
                        child.InvalidateVisual();
                    }
                }
            }
        }
        /// <summary>
        /// Y坐标改变事件
        /// </summary>
        private void LocationY_ValueChanged(object sender, EventArgs e)
        {
            if (IsCanMove)
                return;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(this.mainCanvas); i++)
            {
                if (VisualTreeHelper.GetChild(this.mainCanvas, i).GetType() == typeof(MyImage))
                {
                    MyImage child = (MyImage)VisualTreeHelper.GetChild(this.mainCanvas, i);
                    if (child.IsSelect)
                    {
                        Canvas.SetTop(child, Convert.ToDouble(this.locationY.Value));
                        child.InvalidateVisual();
                    }
                }
            }
        }
        /// <summary>
        /// 宽改变事件
        /// </summary>
        private void ImgWidth_ValueChanged(object sender, EventArgs e)
        {
            if (IsCanMove)
                return;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(this.mainCanvas); i++)
            {
                if (VisualTreeHelper.GetChild(this.mainCanvas, i).GetType() == typeof(MyImage))
                {
                    MyImage child = (MyImage)VisualTreeHelper.GetChild(this.mainCanvas, i);
                    if (child.IsSelect)
                    {
                        child.Width = Convert.ToDouble(this.imgWidth.Value);
                        child.InvalidateVisual();
                    }
                }
            }
        }
        /// <summary>
        /// 高改变事件
        /// </summary>
        private void ImgHeight_ValueChanged(object sender, EventArgs e)
        {
            if (IsCanMove)
                return;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(this.mainCanvas); i++)
            {
                if (VisualTreeHelper.GetChild(this.mainCanvas, i).GetType() == typeof(MyImage))
                {
                    MyImage child = (MyImage)VisualTreeHelper.GetChild(this.mainCanvas, i);
                    if (child.IsSelect)
                    {
                        child.Height = Convert.ToDouble(this.imgHeight.Value);
                        child.InvalidateVisual();
                    }
                }
            }
        }
    }
           

相关博文:

WPF中GDI+图形图像的绘制:(一)绘制文本——动态设置字体、大小、颜色

WPF中GDI+图形图像的绘制:(二)绘制文本——字体描边、渐变、图片叠加

WPF中GDI+图形图像的绘制:(三)绘制图像——实现黑白、浮雕、锐化效果

WPF中GDI+图形图像的绘制:(四)绘制图像——水平垂直镜像与中心旋转

WPF中GDI+图形图像的绘制:(五)绘制图像——蒙板效果

WPF中GDI+图形图像的绘制:(六)绘制图像——鼠标选中后绘制边框

WPF中GDI+图形图像的绘制:(七)绘制图像——鼠标拖动改变位置和大小

WPF中GDI+图形图像的绘制:(八)位置坐标和宽高与控件绑定展示

继续阅读