WPF InkCanvas基本操作代码演示

    WPF的InkCanvas就是一个画板,可以在上面随意涂鸦,每写上一笔,InkCanvas的Strokes集合里就新增一个涂鸦对象,下面的代码演示了基本的操作。

  • 效果图

  •  xaml代码
<Window x:Class="WPF_InkCanvas.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:WPF_InkCanvas"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Image Name="imgMeasure" HorizontalAlignment="Center" Stretch="Uniform"/>
        <InkCanvas Name="inkCanvasMeasure" EditingMode="None" Background="Transparent" HorizontalAlignment="Center" 
                   Width="{Binding ElementName=imgMeasure, Path=ActualWidth}" Height="{Binding ElementName=imgMeasure, Path=ActualHeight}"
                   >
            <!--MouseDown="InkCanvasMeasure_MouseDown" MouseMove="InkCanvasMeasure_MouseMove"-->
            <Label Content="{Binding MeaInfo}" Background="Transparent" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" 
                   FontSize="18" Foreground="Red" IsHitTestVisible="False"/>
        </InkCanvas>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <RadioButton Grid.Column="0" Content="绘制墨迹" Click="RadioButton_Click"/>
            <RadioButton Grid.Column="1" Content="按点擦除" Click="RadioButton_Click"/>
            <RadioButton Grid.Column="2" Content="按线擦除" Click="RadioButton_Click"/>
            <RadioButton Grid.Column="3" Content="选中墨迹" Click="RadioButton_Click"/>
            <RadioButton Grid.Column="4" Content="停止操作" Click="RadioButton_Click"/>
        </Grid>
        <StackPanel Grid.Row="2" Orientation="Horizontal">
            <Button Content="OpenFile" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="OpenFile_Click"/>
            <Button Content="SaveInkCanvas" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="SaveInkCanvas_Click"/>
            <Button Content="LoadInkCanvas" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="LoadInkCanvas_Click"/>
            <Button Content="CopyInkCanvas" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="CopyInkCanvas_Click"/>
            <Button Content="PasteInkCanvas" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="PasteInkCanvas_Click"/>
        </StackPanel>
    </Grid>
</Window>
  • 后台代码
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF_InkCanvas
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        ViewModel viewModel;
        public MainWindow()
        {
            InitializeComponent();

            DrawingAttributes drawingAttributes = new DrawingAttributes
            {
                Color = Colors.Red,
                Width = 2,
                Height = 2,
                StylusTip = StylusTip.Rectangle,
                FitToCurve = true,
                IsHighlighter = false,
                IgnorePressure = true,

            };
            inkCanvasMeasure.DefaultDrawingAttributes = drawingAttributes;

            viewModel = new ViewModel
            {
                MeaInfo = "测试······",
            };

            DataContext = viewModel;
        }

        private void InkCanvasMeasure_MouseDown(object sender, MouseButtonEventArgs e)
        {

        }

        private void InkCanvasMeasure_MouseMove(object sender, MouseEventArgs e)
        {

        }

        private void OpenFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openDialog = new OpenFileDialog
            {
                Filter = "Image Files (*.jpg)|*.jpg|Image Files (*.png)|*.png|Image Files (*.bmp)|*.bmp",
                Title = "Open Image File"
            };
            if (openDialog.ShowDialog() == true)
            {
                BitmapImage image = new BitmapImage();
                image.BeginInit();
                image.UriSource = new Uri(openDialog.FileName, UriKind.RelativeOrAbsolute);
                image.EndInit();
                imgMeasure.Source = image;
            }
        }

        private void RadioButton_Click(object sender, RoutedEventArgs e)
        {
            if ((sender as RadioButton).Content.ToString() == "绘制墨迹")
            {
                inkCanvasMeasure.EditingMode = InkCanvasEditingMode.Ink;
            }

            else if ((sender as RadioButton).Content.ToString() == "按点擦除")
            {
                inkCanvasMeasure.EditingMode = InkCanvasEditingMode.EraseByPoint;
            }

            else if ((sender as RadioButton).Content.ToString() == "按线擦除")
            {
                inkCanvasMeasure.EditingMode = InkCanvasEditingMode.EraseByStroke;
            }

            else if ((sender as RadioButton).Content.ToString() == "选中墨迹")
            {
                inkCanvasMeasure.EditingMode = InkCanvasEditingMode.Select;
            }

            else if ((sender as RadioButton).Content.ToString() == "停止操作")
            {
                inkCanvasMeasure.EditingMode = InkCanvasEditingMode.None;
            }
        }

        private void SaveInkCanvas_Click(object sender, RoutedEventArgs e)
        {
            FileStream fileStream = new FileStream("inkCanvas.isf", FileMode.Create, FileAccess.ReadWrite);
            inkCanvasMeasure.Strokes.Save(fileStream);
            fileStream.Close();
        }

        private void LoadInkCanvas_Click(object sender, RoutedEventArgs e)
        {
            FileStream fileStream = new FileStream("inkCanvas.isf", FileMode.Open, FileAccess.Read);
            inkCanvasMeasure.Strokes = new StrokeCollection(fileStream);
            fileStream.Close();
        }

        private void CopyInkCanvas_Click(object sender, RoutedEventArgs e)
        {
            inkCanvasMeasure.CopySelection();
        }
        private void PasteInkCanvas_Click(object sender, RoutedEventArgs e)
        {
            inkCanvasMeasure.Paste();
        }
    }
}
  • ViewModel.cs代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WPF_InkCanvas
{
    class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private string meaInfo;
        public string MeaInfo
        {
            get => meaInfo;
            set
            {
                meaInfo = value;
                OnPropertyChanged("MeaInfo");
            }
        }
    }
}

    补充说明:将Image和InkCanvas放到一个Grid里,并且将InkCanvas的长宽绑定到Image,这样Image和InkCanvas的位置就是对应的,方便我后续在InkCanvas上提取Image的感兴趣区域;InkCanvas里加了一个Label可以实现类似图片上添加文字说明的功能,要设置Label的IsHitTestVisible="False",不然点击事件就没办法触发了。

猜你喜欢

转载自blog.csdn.net/u012366767/article/details/81265922
WPF