浏览代码

注释-内容选择

OYXH\oyxh 2 年之前
父节点
当前提交
0469fd802f

二进制
PDF Office/ComPDFKit.Viewer.dll


+ 2 - 2
PDF Office/CustomControl/TextBoxWithTip.xaml

@@ -31,8 +31,8 @@
                                 FontSize="12"
                                 Foreground="{StaticResource color.field.text.tips}"
                                 Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TextBoxWithTip}, Path=TipText}"
-                                Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TextBoxWithTip}, Path=ShowTip}"
-                                TextWrapping="Wrap" />
+                                TextWrapping="Wrap"
+                                Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TextBoxWithTip}, Path=ShowTip}" />
                         </Grid>
                         <ControlTemplate.Triggers>
                             <Trigger SourceName="TextBox" Property="IsError" Value="True">

+ 645 - 0
PDF Office/Helper/PageEditTool.cs

@@ -0,0 +1,645 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing.Imaging;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Windows.Media.Imaging;
+using System.Windows;
+
+namespace PDF_Office.Helper
+{
+    public enum FileExtension
+    {
+        JPG = 255216,
+        GIF = 7173,
+        PNG = 13780,
+        SWF = 6787,
+        RAR = 8297,
+        ZIP = 8075,
+        _7Z = 55122,
+        VALIDFILE = 9999999
+    }
+
+    /// <summary>
+    /// 页面编辑的工具类
+    /// </summary>
+    public static class PageEditTool
+    {
+        [DllImport("user32.dll")]
+        private static extern IntPtr SetCapture(long hWnd);
+
+        [DllImport("user32.dll")]
+        private static extern long ReleaseCapture();
+
+        /// <summary>
+        /// 打开路径并定位文件...对于@"h:\Bleacher Report - Hardaway with the safe call ??.mp4"这样的,explorer.exe /select,d:xxx不认,用API整它
+        /// </summary>
+        /// <param name="filePath">文件绝对路径</param>
+        [DllImport("shell32.dll", ExactSpelling = true)]
+        private static extern void ILFree(IntPtr pidlList);
+
+        [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
+        private static extern IntPtr ILCreateFromPathW(string pszPath);
+
+        [DllImport("shell32.dll", ExactSpelling = true)]
+        private static extern int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);
+
+        /// <summary>
+        /// 打开文件夹浏览,并选中一个文件(对于文件名称比较不规范的,可以用这个)
+        /// </summary>
+        /// <param name="filePath"></param>
+        public static void ExplorerFile(string filePath)
+        {
+            try
+            {
+                if (!File.Exists(filePath) && !Directory.Exists(filePath))
+                    return;
+
+                if (Directory.Exists(filePath))
+                    Process.Start(@"explorer.exe", "/select,\"" + filePath + "\"");
+                else
+                {
+                    IntPtr pidlList = ILCreateFromPathW(filePath);
+                    if (pidlList != IntPtr.Zero)
+                    {
+                        try
+                        {
+                            Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0));
+                        }
+                        finally
+                        {
+                            ILFree(pidlList);
+                        }
+                    }
+                }
+            }
+            catch { }
+        }
+
+        /// <summary>
+        /// 强制捕获鼠标
+        /// </summary>
+        /// <param name="hwd"></param>
+        public static void DOSetCapture(long hwd)
+        {
+            SetCapture(hwd);
+        }
+
+        public static void DoReleaseCapture()
+        {
+            ReleaseCapture();
+        }
+
+        /// <summary>
+        /// 返回文件占有的大小
+        /// </summary>
+        /// <param name="filePath"></param>
+        /// <returns></returns>
+        public static string GetFileSize(string filePath)
+        {
+            //判断当前路径所指向的是否为文件
+            if (File.Exists(filePath))
+            {
+                //定义一个FileInfo对象,使之与filePath所指向的文件向关联,
+                //以获取其大小
+                FileInfo fileInfo = new FileInfo(filePath);
+                var size = fileInfo.Length;
+                string strSize = "";
+                if (size < 1024)
+                {
+                    strSize = Math.Round(size / 1024.0, 3) + " KB";
+                }
+                else if (size / 1024 > 1024)
+                {
+                    strSize = Math.Round(size / 1024 / 1024.0, 1) + " MB";
+                }
+                else
+                {
+                    strSize = Math.Round(size / 1024.0, 1) + " KB";
+                }
+                return strSize;
+            }
+            else
+            {
+                return string.Empty;
+            }
+        }
+
+        /// <summary>
+        /// 用照片查看器查看指定路径的图片
+        /// </summary>
+        /// <param name="Path">带文件名的绝对路径</param>
+        public static void BrowsePicture(string Path)
+        {
+            //建立新的系统进程
+            System.Diagnostics.Process process = new System.Diagnostics.Process();
+            //设置文件名,此处为图片的真实路径+文件名
+            process.StartInfo.FileName = Path;
+            //此为关键部分。设置进程运行参数,此时为最大化窗口显示图片。
+            process.StartInfo.Arguments = "rundll32.exe C://WINDOWS//system32//shimgvw.dll,ImageView_Fullscreen";
+            //此项为是否使用Shell执行程序,因系统默认为true,此项也可不设,但若设置必须为true
+            process.StartInfo.UseShellExecute = true;
+            //此处可以更改进程所打开窗体的显示样式,可以不设
+            process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
+            process.Start();
+            process.Dispose();
+        }
+
+        /// <summary>
+        /// 校验PageRange 输入是否合法,且可返回List<int> Pages  存放的索引值
+        /// </summary>
+        /// <param name="pageList">返回的页面集合</param>
+        /// <param name="pageRange">需要判断的文本</param>
+        /// <param name="count">页面总数</param>
+        /// <param name="enumerationSeparator">例 new char[] { ',' }</param>
+        /// <param name="rangeSeparator">例 new char[] { '-' }</param>
+        /// <param name="inittag"></param>
+        /// <returns></returns>
+        public static bool GetPagesInRange(ref List<int> pageList, string pageRange, int count, char[] enumerationSeparator, char[] rangeSeparator, bool inittag = false)
+        {
+            string[] rangeSplit = pageRange.Split(enumerationSeparator);//根据分隔符 拆分字符串
+
+            pageList.Clear();
+
+            foreach (string range in rangeSplit)
+            {
+                int starttag = 1;
+                if (inittag)
+                {
+                    starttag = 0;
+                }
+                if (range.Contains("-"))//连续页
+                {
+                    try
+                    {
+                        string[] limits = range.Split(rangeSeparator);//对子字符串再根据”-“ 拆分
+                        if (limits.Length >= 2 && !string.IsNullOrWhiteSpace(limits[0]) && !string.IsNullOrWhiteSpace(limits[1]))
+                        {
+                            int start = int.Parse(limits[0]);
+                            int end = int.Parse(limits[1]);
+
+                            if ((start < starttag) || (end > count) || (start > end))
+                            {
+                                //throw new Exception(string.Format("Invalid page(s) in range {0} - {1}", start, end));
+                                return false;
+                            }
+
+                            for (int i = start; i <= end; ++i)
+                            {
+                                if (pageList.Contains(i))
+                                {
+                                    // throw new Exception(string.Format("Invalid page(s) in range {0} - {1}", start, end));
+                                    return false;
+                                }
+
+                                pageList.Add(i - 1);
+                            }
+                            continue;
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        // MessageBox.Show("请检查符号或页码范围是否正确。","提示",MessageBoxButton.OKCancel,MessageBoxImage.Warning);
+                        return false;
+                    }
+                }
+                int pageNr;
+                try
+                {
+                    // Single page
+                    pageNr = int.Parse(range);//单页
+                }
+                catch (Exception)//格式不正确时
+                {
+                    return false;
+                }
+                if (pageNr < starttag || pageNr > count)
+                {
+                    return false;
+                    //throw new Exception(string.Format("Invalid page {0}", pageNr));
+                }
+                if (pageList.Contains(pageNr))
+                {
+                    return false;
+                    // throw new Exception(string.Format("Invalid page {0}", pageNr));
+                }
+                pageList.Add(pageNr - 1);
+            }
+            return true;
+        }
+
+        /// <summary>
+        ///  返回指定路径的图标
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns></returns>
+        public static BitmapSource ToBitmapSource(string path)
+        {
+            System.Drawing.Icon ico = System.Drawing.Icon.ExtractAssociatedIcon(path);
+            System.Drawing.Bitmap bitmap = ico.ToBitmap();
+            BitmapSource returnSource;
+            try
+            {
+                returnSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
+            }
+            catch
+            {
+                returnSource = null;
+            }
+            return returnSource;
+        }
+
+        public static string GetPageParmFromList(List<int> pagesList)
+        {
+            string pageParam = "";
+            if (pagesList.Count != 0)
+            {
+                pagesList.Sort();//先对页码排序
+
+                for (int i = 0; i < pagesList.Count; i++)
+                {
+                    if (i == 0)
+                    {
+                        pageParam += pagesList[0].ToString();
+                    }
+                    else
+                    {
+                        if (pagesList[i] == pagesList[i - 1] + 1)//页码连续
+                        {
+                            if (i >= 2)
+                            {
+                                if (pagesList[i - 1] != pagesList[i - 2] + 1)
+                                    pageParam += "-";
+                            }
+                            else
+                                pageParam += "-";
+
+                            if (i == pagesList.Count - 1)
+                            {
+                                pageParam += pagesList[i].ToString();
+                            }
+                        }
+                        else//页码不连续时
+                        {
+                            if (i >= 2)
+                            {
+                                if (pagesList[i - 1] == pagesList[i - 2] + 1)
+                                    pageParam += pagesList[i - 1].ToString();
+                            }
+                            pageParam += "," + pagesList[i].ToString();
+                        }
+                    }
+                }
+            }
+            return pageParam;
+        }
+
+        /// <summary>
+        /// 检测文件是否重复  追加尾号
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns></returns>
+        public static string CreateFilePath(string path)
+        {
+            int i = 1;
+            string oldDestName = path;
+            do
+            {
+                if (File.Exists(path))
+                {
+                    int lastDot = oldDestName.LastIndexOf('.');
+
+                    string fileExtension = string.Empty;
+
+                    string fileName = oldDestName;
+
+                    if (lastDot > 0)
+                    {
+                        fileExtension = fileName.Substring(lastDot);
+
+                        fileName = fileName.Substring(0, lastDot);
+                    }
+
+                    path = fileName + string.Format(@"({0})", i) + fileExtension;
+                }
+                ++i;
+            } while (File.Exists(path));
+            return path;
+        }
+
+        /// <summary>
+        /// 检查文件夹是否重复  追加尾号
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns></returns>
+        public static string CreateFolder(string folder)
+        {
+            try
+            {
+                int i = 1;
+                string oldDestName = folder;
+                DirectoryInfo info = new DirectoryInfo(folder);
+                do
+                {
+                    info = new DirectoryInfo(folder);
+                    if (info.Exists)
+                    {
+                        string fileName = oldDestName;
+
+                        folder = fileName + string.Format(@"({0})", i);
+                    }
+                    ++i;
+                } while (info.Exists);
+                info.Create();
+            }
+            catch { return null; }
+            return folder;
+        }
+
+        /// <summary>
+        /// 文件名称是否合法
+        /// </summary>
+        /// <param name="fileName">文件名</param>
+        /// <returns>返回true是合法</returns>
+        public static bool IsValidFileName(string fileName)
+        {
+            try
+            {
+                foreach (char invalidChar in Path.GetInvalidFileNameChars())
+                {
+                    if (fileName.Contains(invalidChar.ToString()))
+                        return false;
+                }
+                return true;
+            }
+            catch
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 悬浮提示框(气泡形式)
+        /// </summary>
+        /// <param name="control">显示提示的控件</param>
+        /// <param name="tipMsg">内容</param>
+        /// <param name="tipTitle">标题</param>
+        /// <param name="delay">调用该函数而显示时间</param>
+        /// <param name="autoPopDelay">悬浮控件上的显示时间</param>
+        public static async void ShowToolTip(Control control, string tipMsg, string tipTitle = "", int delay = 2000, int autoPopDelay = 0)
+        {
+            if (control == null || string.IsNullOrEmpty(tipMsg))
+                return;
+            try
+            {
+                ToolTip toolTip = new ToolTip();
+
+                //if (string.IsNullOrEmpty(tipTitle))
+                //    tipTitle = App.MainPageLoader.GetString("Main_HintWarningTilte");
+
+                toolTip.ToolTipTitle = tipTitle;
+                toolTip.SetToolTip(control, tipMsg);
+                toolTip.IsBalloon = true;
+                toolTip.ToolTipIcon = ToolTipIcon.Warning;
+                toolTip.ShowAlways = false;
+                toolTip.AutoPopDelay = autoPopDelay;
+                toolTip.Show(tipMsg, control);
+                await Task.Delay(delay);
+                toolTip.Hide(control);
+            }
+            catch { }
+        }
+
+        public static BitmapImage ToBitmapImage(System.Drawing.Bitmap ImageOriginal)
+        {
+            System.Drawing.Bitmap ImageOriginalBase = new System.Drawing.Bitmap(ImageOriginal);
+            BitmapImage bitmapImage = new BitmapImage();
+            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
+            {
+                //ImageOriginalBase.Save(ms, ImageOriginalBase.RawFormat);
+                ImageOriginalBase.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
+                bitmapImage.BeginInit();
+                bitmapImage.StreamSource = ms;
+                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
+                bitmapImage.EndInit();
+                bitmapImage.Freeze();
+            }
+            return bitmapImage;
+        }
+
+        /// <summary>
+        /// 获取图片的旋转角度
+        /// 获取后可以 通过bitmap的RotateFlip 回位
+        /// </summary>
+        /// <param name="path">文件路径</param>
+        /// <returns></returns>
+        public static int GetPictureRotation(string path)
+        {
+            int rotate = 0;
+            using (var image = System.Drawing.Image.FromFile(path))
+            {
+                foreach (var prop in image.PropertyItems)
+                {
+                    if (prop.Id == 0x112)
+                    {
+                        if (prop.Value[0] == 6)
+                            rotate = 90;
+                        if (prop.Value[0] == 8)
+                            rotate = -90;
+                        if (prop.Value[0] == 3)
+                            rotate = 180;
+                        prop.Value[0] = 1;
+                    }
+                }
+            }
+            return rotate;
+        }
+
+        public static byte[] GetImageByteFromPath(string ImagePath, string fileExt, out double width, out double height)
+        {
+            try
+            {
+                #region 跟图章一样的转换方法。
+
+                if (ImagePath != null && ImagePath.Length > 0 && File.Exists(ImagePath))
+                {
+                    FileStream fileData = File.OpenRead(ImagePath);
+                    BitmapFrame frame = null;
+                    width = 0;
+                    height = 0;
+
+                    if (fileExt.Contains(".jpg") || fileExt.Contains(".jpeg"))
+                    {
+                        JpegBitmapDecoder decoder = (JpegBitmapDecoder)JpegBitmapDecoder.Create(fileData, BitmapCreateOptions.None, BitmapCacheOption.Default);
+                        frame = decoder.Frames[0];
+                        width = frame.Width;
+                        height = frame.Height;
+                    }
+                    else if (fileExt.Contains(".png"))
+                    {
+                        PngBitmapDecoder decoder = (PngBitmapDecoder)PngBitmapDecoder.Create(fileData, BitmapCreateOptions.None, BitmapCacheOption.Default);
+                        frame = decoder.Frames[0];
+                        width = frame.Width;
+                        height = frame.Height;
+                    }
+                    else if (fileExt.Contains(".bmp"))
+                    {
+                        BmpBitmapDecoder decoder = (BmpBitmapDecoder)BmpBitmapDecoder.Create(fileData, BitmapCreateOptions.None, BitmapCacheOption.Default);
+                        frame = decoder.Frames[0];
+                        width = frame.Width;
+                        height = frame.Height;
+                    }
+                    else//默认采用png的解码方式
+                    {
+                        BitmapDecoder decoder = BitmapDecoder.Create(fileData, BitmapCreateOptions.None, BitmapCacheOption.Default);
+                        frame = decoder.Frames[0];
+                        width = frame.Width;
+                        height = frame.Height;
+                    }
+
+                    if (frame != null)
+                    {
+                        var ImageArray = new byte[frame.PixelWidth * frame.PixelHeight * 4];
+                        frame.CopyPixels(ImageArray, frame.PixelWidth * 4, 0);
+                        return ImageArray;
+                    }
+                    return null;
+                }
+                width = 0;
+                height = 0;
+                return null;
+
+                #endregion 跟图章一样的转换方法。
+            }
+            catch (Exception ex)
+            {
+                width = 0;
+                height = 0;
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// BitmapImage 转Bitmap
+        /// </summary>
+        /// <param name="bitmapImage"></param>
+        /// <param name="isPng"></param>
+        /// <returns></returns>
+        public static Bitmap GetBitmapByBitmapImage(BitmapImage bitmapImage, bool isPng = false)
+        {
+            Bitmap bitmap;
+            MemoryStream outStream = new MemoryStream();
+            BitmapEncoder enc = new JpegBitmapEncoder();
+            if (isPng)
+            {
+                enc = new PngBitmapEncoder();
+            }
+            enc.Frames.Add(BitmapFrame.Create(bitmapImage));
+            enc.Save(outStream);
+            bitmap = new Bitmap(outStream);
+            return bitmap;
+        }
+
+        /// <summary>
+        /// 根据图片数据判断图片类型
+        /// </summary>
+        /// <param name="fileName"></param>
+        /// <returns></returns>
+        public static FileExtension CheckTextFile(string fileName)
+        {
+            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
+            System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
+            string fileType = string.Empty; ;
+            try
+            {
+                byte data = br.ReadByte();
+                fileType += data.ToString();
+                data = br.ReadByte();
+                fileType += data.ToString();
+                FileExtension extension;
+                try
+                {
+                    extension = (FileExtension)Enum.Parse(typeof(FileExtension), fileType);
+                }
+                catch
+                {
+                    extension = FileExtension.VALIDFILE;
+                }
+                return extension;
+            }
+            catch (Exception ex)
+            {
+                throw ex;
+            }
+            finally
+            {
+                if (fs != null)
+                {
+                    fs.Close();
+                    br.Close();
+                }
+            }
+        }
+
+        /// <summary>
+        /// 压缩图片到600*600以内,压缩成功后返回压缩完成的缓存路径
+        /// 如果压缩 失败 返回原图路径
+        /// </summary>
+        /// <param name="filePath"></param>
+        /// <returns></returns>
+        public static string CompressImage(string filePath, int maxwidth = 600)
+        {
+            try
+            {
+                string sourcepath = filePath;
+                var guid = Guid.NewGuid().ToString();
+                string folder = Path.Combine(App.CurrentPath, "Temp");
+                if (!Directory.Exists(folder))
+                {
+                    Directory.CreateDirectory(folder);
+                }
+                var path = System.IO.Path.Combine(App.CurrentPath, "Temp", guid);
+
+                Bitmap bitmap = new Bitmap(sourcepath);
+
+                var b = bitmap;
+                //bitmap.Dispose();
+
+                double scale = Math.Min((double)maxwidth / b.Width, (double)maxwidth / b.Height);
+                scale = Math.Min(scale, 1);
+                System.Drawing.Size newsize = new System.Drawing.Size(maxwidth, maxwidth);
+                newsize.Width = (int)(scale * b.Width);
+                newsize.Height = (int)(scale * b.Height);
+
+                if (!File.Exists(path))
+                {
+                    if (CheckTextFile(sourcepath) == FileExtension.PNG)
+                    {
+                        using (var bp = new Bitmap(b, (int)newsize.Width, (int)newsize.Height))
+                        {
+                            bp.Save(path, ImageFormat.Png);
+                        }
+                    }
+                    else
+                    {
+                        using (var bp = new Bitmap(b, (int)newsize.Width, (int)newsize.Height))
+                        {
+                            bp.Save(path, ImageFormat.Jpeg);
+                        }
+                    }
+                }
+                return path;
+            }
+            catch
+            {
+                return filePath;
+            }
+        }
+    }
+}

+ 9 - 0
PDF Office/PDF Office.csproj

@@ -312,6 +312,7 @@
     <Compile Include="Helper\DragDropHelper.cs" />
     <Compile Include="Helper\HomePageEditHelper.cs" />
     <Compile Include="Helper\ObservableDictionary.cs" />
+    <Compile Include="Helper\PageEditTool.cs" />
     <Compile Include="Helper\PasswordBoxHelper.cs" />
     <Compile Include="Helper\RichTextBoxHelper.cs" />
     <Compile Include="Helper\SDKLisenceHelper.cs" />
@@ -477,6 +478,7 @@
     <Compile Include="ViewModels\HomePanel\PDFTools\QuickToolsContentViewModel.cs" />
     <Compile Include="ViewModels\PropertyPanel\AnnotPanel\SignatureAnnotPropertyViewModel.cs" />
     <Compile Include="ViewModels\PropertyPanel\AnnotPanel\SignatureCreateDialogViewModel.cs" />
+    <Compile Include="ViewModels\PropertyPanel\AnnotPanel\SnapshotEditMenuViewModel.cs" />
     <Compile Include="ViewModels\PropertyPanel\PDFEdit\ImageEditPropertyViewModel.cs" />
     <Compile Include="ViewModels\PropertyPanel\PDFEdit\TextEditPropertyViewModel.cs" />
     <Compile Include="ViewModels\PropertyPanel\Scan\ScanPropertyPanelViewModel.cs" />
@@ -973,6 +975,9 @@
     <Compile Include="Views\PropertyPanel\AnnotPanel\SignatureCreateDialog.xaml.cs">
       <DependentUpon>SignatureCreateDialog.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Views\PropertyPanel\AnnotPanel\SnapshotEditMenu.xaml.cs">
+      <DependentUpon>SnapshotEditMenu.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Views\PropertyPanel\AnnotPanel\StampAnnotProperty.xaml.cs">
       <DependentUpon>StampAnnotProperty.xaml</DependentUpon>
     </Compile>
@@ -1665,6 +1670,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Views\PropertyPanel\AnnotPanel\SnapshotEditMenu.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Views\PropertyPanel\AnnotPanel\StampAnnotProperty.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 2 - 2
PDF Office/Styles/ButtonStyle.xaml

@@ -390,8 +390,8 @@
     </ControlTemplate>
 
     <!--
-    Style for Btn.cta
-    样式里仅设置了背景色和文字颜色变化,字体大小和控件宽度需要调用时设置
+        Style for Btn.cta
+        样式里仅设置了背景色和文字颜色变化,字体大小和控件宽度需要调用时设置
     -->
     <Style x:Key="Btn.cta" TargetType="{x:Type Button}">
         <Setter Property="FocusVisualStyle" Value="{x:Null}" />

+ 77 - 2
PDF Office/Styles/ContextMenuStyle.xaml

@@ -19,7 +19,6 @@
                 </Path>
             </MenuItem.Icon>
         </MenuItem>
-
     </ContextMenu>
 
     <ContextMenu x:Key="SelectAnnotContextMenu" FontSize="14">
@@ -82,6 +81,83 @@
         </MenuItem>
     </ContextMenu>
 
+    <!--  注释-内容选择-右键菜单  -->
+    <ContextMenu x:Key="SnapshotContextMenu" FontSize="14">
+        <!--<ContextMenu.ItemContainerStyle>
+            <Style TargetType="MenuItem">
+                <Setter Property="Padding" Value="0,7,0,7" />
+                <Setter Property="VerticalContentAlignment" Value="Center" />
+                <Setter Property="HorizontalContentAlignment" Value="Left" />
+            </Style>
+        </ContextMenu.ItemContainerStyle>-->
+        <MenuItem
+            Name="BtnSnapCopy"
+            Header="复制"
+            IsEnabled="True">
+            <!--<MenuItem.Icon>
+            <Path Data="M5.24031 1.5H0.5V14.5H15.5V4H7.24031L5.24031 1.5ZM1.5 13.5V2.5H4.75969L6.75969 5H14.5V13.5H1.5ZM4 7.5H12V6.5H4V7.5Z" Fill="Black">
+            <Path.RenderTransform>
+            <TranslateTransform X="3.0000" Y="0" />
+            </Path.RenderTransform>
+            </Path>
+            </MenuItem.Icon>-->
+        </MenuItem>
+
+        <MenuItem
+            Name="BtnSnapExport"
+            Header="导出"
+            IsEnabled="True">
+            <!--<MenuItem.Icon>
+            <Path Data="M5.24031 1.5H0.5V14.5H15.5V4H7.24031L5.24031 1.5ZM1.5 13.5V2.5H4.75969L6.75969 5H14.5V13.5H1.5ZM4 7.5H12V6.5H4V7.5Z" Fill="Black">
+            <Path.RenderTransform>
+            <TranslateTransform X="3.0000" Y="0" />
+            </Path.RenderTransform>
+            </Path>
+            </MenuItem.Icon>-->
+            <MenuItem Name="MenuExportPNG" Header="PNG" />
+            <MenuItem Name="MenuExportJPG" Header="JPG" />
+            <MenuItem Name="MenuExportPDF" Header="PDF" />
+        </MenuItem>
+
+        <MenuItem
+            Name="BtnSnapCropping"
+            Header="裁剪"
+            IsEnabled="True">
+            <!--<MenuItem.Icon>
+            <Path Data="M5.24031 1.5H0.5V14.5H15.5V4H7.24031L5.24031 1.5ZM1.5 13.5V2.5H4.75969L6.75969 5H14.5V13.5H1.5ZM4 7.5H12V6.5H4V7.5Z" Fill="Black">
+            <Path.RenderTransform>
+            <TranslateTransform X="3.0000" Y="0" />
+            </Path.RenderTransform>
+            </Path>
+            </MenuItem.Icon>-->
+        </MenuItem>
+
+        <MenuItem
+            Name="BtnSnapZoom"
+            Header="缩放至所选区域"
+            IsEnabled="True">
+            <!--<MenuItem.Icon>
+            <Path Data="M5.24031 1.5H0.5V14.5H15.5V4H7.24031L5.24031 1.5ZM1.5 13.5V2.5H4.75969L6.75969 5H14.5V13.5H1.5ZM4 7.5H12V6.5H4V7.5Z" Fill="Black">
+            <Path.RenderTransform>
+            <TranslateTransform X="3.0000" Y="0" />
+            </Path.RenderTransform>
+            </Path>
+            </MenuItem.Icon>-->
+        </MenuItem>
+
+        <MenuItem
+            Name="BtnSnapPrint"
+            Header="打印"
+            IsEnabled="True">
+            <!--<MenuItem.Icon>
+            <Path Data="M5.24031 1.5H0.5V14.5H15.5V4H7.24031L5.24031 1.5ZM1.5 13.5V2.5H4.75969L6.75969 5H14.5V13.5H1.5ZM4 7.5H12V6.5H4V7.5Z" Fill="Black">
+            <Path.RenderTransform>
+            <TranslateTransform X="3.0000" Y="0" />
+            </Path.RenderTransform>
+            </Path>
+            </MenuItem.Icon>-->
+        </MenuItem>
+    </ContextMenu>
     <ContextMenu x:Key="RedactionContextMenu">
         <MenuItem
             Name="MenuDelete"
@@ -95,5 +171,4 @@
         <MenuItem Name="MenuApply" Header="Apply Redactions" />
         <MenuItem Name="MenuErase" Header="Erase Redactions" />
     </ContextMenu>
-
 </ResourceDictionary>

+ 2 - 2
PDF Office/Styles/CustomBtnStyle.xaml

@@ -477,7 +477,7 @@
                             <Setter TargetName="optionMark" Property="Fill" Value="{StaticResource RadioButton.Pressed.Glyph}" />
                         </Trigger>
                         <Trigger Property="IsChecked" Value="true">
-                            <Setter  TargetName="radioButtonBorder" Property="Background" Value="Red" />
+                            <Setter TargetName="radioButtonBorder" Property="Background" Value="Red" />
                             <Setter TargetName="optionMark" Property="Fill" Value="{StaticResource RadioButton.Pressed.Glyph}" />
                         </Trigger>
                         <Trigger Property="IsChecked" Value="{x:Null}">
@@ -550,7 +550,7 @@
         </Style.Triggers>
     </Style>
 
-    <!--带有蓝色边框的单选按钮-->
+    <!--  带有蓝色边框的单选按钮  -->
     <Style x:Key="BlueBorderRadionButtonWithCorner" TargetType="{x:Type RadioButton}">
         <Setter Property="Background" Value="Transparent" />
         <Setter Property="BorderBrush" Value="Transparent" />

+ 2 - 1
PDF Office/Styles/RadioButtonStyle.xaml

@@ -67,7 +67,8 @@
                             VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                             Background="{TemplateBinding Background}"
                             BorderBrush="{TemplateBinding BorderBrush}"
-                            BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4">
+                            BorderThickness="{TemplateBinding BorderThickness}"
+                            CornerRadius="4">
                             <Rectangle
                                 x:Name="optionMark"
                                 Width="{TemplateBinding Width}"

+ 358 - 0
PDF Office/ViewModels/PropertyPanel/AnnotPanel/SnapshotEditMenuViewModel.cs

@@ -0,0 +1,358 @@
+using ComPDFKitViewer.AnnotEvent;
+using ComPDFKitViewer.PdfViewer;
+using Prism.Commands;
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+using System.Windows;
+using System.Windows.Media.Imaging;
+using System.Drawing;
+using static Dropbox.Api.Sharing.MemberAction;
+using System.IO;
+using PDF_Office.Helper;
+using Microsoft.Win32;
+using System.Windows.Interop;
+using PDF_Office.CustomControl;
+using System.Windows.Controls;
+using PDF_Office.Model.Dialog.HomePageToolsDialogs.HomePagePrinter;
+using ComPDFKit.PDFPage;
+using System.Drawing.Printing;
+using System.Security.Policy;
+using Microsoft.AppCenter.Utils.Files;
+using File = System.IO.File;
+using Directory = System.IO.Directory;
+using System.Drawing.Imaging;
+using Microsoft.Office.Interop.Word;
+using static Dropbox.Api.Sharing.ListFileMembersIndividualResult;
+
+namespace PDF_Office.ViewModels.PropertyPanel.AnnotPanel
+{
+    internal class SnapshotEditMenuViewModel : BindableBase
+    {
+        public CustomIconToggleBtn ToggleBtn { get; set; }
+        public SnapshotEditToolArgs SnapToolArgs { get; set; }
+        public CPDFViewer PDFViewer { get; set; }
+
+        private CPDFViewer saveToPDFViewer = new CPDFViewer();
+
+        public event EventHandler<KeyValuePair<string, object>> SnapToolEvent;
+
+        public DelegateCommand SnapCopyCommand { get; set; }
+
+        public DelegateCommand ExportPNGCommand { get; set; }
+
+        public DelegateCommand ExportJPGCommand { get; set; }
+
+        public DelegateCommand ExportPDFCommand { get; set; }
+        public DelegateCommand CroppingCommand { get; set; }
+
+        public DelegateCommand PrintCommand { get; set; }
+
+        public SnapshotEditMenuViewModel()
+        {
+            SnapCopyCommand = new DelegateCommand(SnapCopyEvent);
+            ExportPNGCommand = new DelegateCommand(ExportPNGEvent);
+            ExportJPGCommand = new DelegateCommand(ExportJPGEvent);
+            ExportPDFCommand = new DelegateCommand(ExportPDFEvent);
+            CroppingCommand = new DelegateCommand(CroppingEvent);
+            PrintCommand = new DelegateCommand(PrintEvent);
+        }
+
+        private void PrintEvent()
+        {
+            if (SnapToolArgs != null && PDFViewer != null && PDFViewer.ToolManager != null)
+            {
+                try
+                {
+                    WriteableBitmap saveBitmap = SnapToolArgs.GetSnapshotImage();
+                    if (saveBitmap != null)
+                    {
+                        PrintDialog printDlg = new PrintDialog();
+                        if (printDlg.ShowDialog() == true)
+                        {
+                            DrawingVisual visualItem = new DrawingVisual();
+                            DrawingContext drawContext = visualItem.RenderOpen();
+                            drawContext.DrawImage(saveBitmap, new Rect(0, 0, saveBitmap.Width, saveBitmap.Height));
+                            drawContext.Close();
+                            printDlg.PrintVisual(visualItem, "Snapshot");
+                        }
+                    }
+                    PDFViewer.SetMouseMode(MouseModes.PanTool);
+                    if (SnapToolEvent != null)
+                    {
+                        KeyValuePair<string, object> param = new KeyValuePair<string, object>("CloseSnap", null);
+                        SnapToolEvent.Invoke(this, param);
+                    }
+                }
+                catch (Exception ex)
+                {
+                }
+            }
+        }
+
+        private void CroppingEvent()
+        {
+            if (SnapToolArgs != null && PDFViewer != null && PDFViewer.ToolManager != null)
+            {
+                SnapToolArgs.SaveSnapshotToClipboard();
+                PDFViewer.SetMouseMode(MouseModes.PanTool);
+                if (SnapToolEvent != null)
+                {
+                    KeyValuePair<string, object> param = new KeyValuePair<string, object>("CloseSnap", null);
+                    SnapToolEvent.Invoke(this, param);
+                }
+            }
+        }
+
+        private void ExportPDFEvent()
+        {
+            SnapshotEditExport("PDF");
+        }
+
+        private void ExportJPGEvent()
+        {
+            SnapshotEditExport("JPG");
+        }
+
+        private void ExportPNGEvent()
+        {
+            SnapshotEditExport("PNG");
+        }
+
+        private void SnapshotEditExport(string type)
+        {
+            if (SnapToolArgs != null && PDFViewer != null && PDFViewer.ToolManager != null)
+            {
+                SaveFileDialog dlg = new SaveFileDialog();
+                switch (type)
+                {
+                    case "PNG":
+                        dlg.Filter = "PNG|*.png";
+                        break;
+
+                    case "JPG":
+                        dlg.Filter = "JPG|*.jpg";
+                        break;
+
+                    case "PDF":
+                        dlg.Filter = "PDF|*.pdf";
+                        break;
+                }
+
+                dlg.FileName = PDFViewer.Document.FileName;
+                if (dlg.FileName == null || dlg.FileName.Trim().Length == 0)
+                {
+                    dlg.FileName = "Blank" + DateTime.Now.ToString("yyyyMMddHHmmss");
+                }
+                if (dlg.ShowDialog() == true)
+                {
+                    string fileName = dlg.FileName;
+                    WriteableBitmap saveBitmap = SnapToolArgs.GetSnapshotImage();
+                    if (saveBitmap != null)
+                    {
+                        if (dlg.SafeFileName.ToLower().EndsWith(".jpg"))
+                        {
+                            Stream saveStream = dlg.OpenFile();
+                            JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
+                            BitmapFrame frame = BitmapFrame.Create(saveBitmap);
+                            jpgEncoder.Frames.Add(frame);
+                            jpgEncoder.Save(saveStream);
+                            saveStream.Dispose();
+                            //导出后打开对应文件夹
+                            PageEditTool.ExplorerFile(dlg.FileName);
+                        }
+                        else if (dlg.SafeFileName.ToLower().EndsWith(".png"))
+                        {
+                            Stream saveStream = dlg.OpenFile();
+                            PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
+                            BitmapFrame frame = BitmapFrame.Create(saveBitmap);
+                            pngEncoder.Frames.Add(frame);
+                            pngEncoder.Save(saveStream);
+                            saveStream.Dispose();
+                            //导出后打开对应文件夹
+                            PageEditTool.ExplorerFile(dlg.FileName);
+                        }
+                        else if (dlg.SafeFileName.ToLower().EndsWith(".pdf"))
+                        {
+                            //Stream saveStream = dlg.OpenFile();
+
+                            string imagePath = SaveImage(saveBitmap);
+                            if (CreateFile(imagePath))
+                            {
+                                bool result = saveToPDFViewer.Document.WriteToFilePath(dlg.FileName);
+                            }
+
+                            //saveStream.Dispose();
+                            //导出后打开对应文件夹
+                            PageEditTool.ExplorerFile(dlg.FileName);
+                        }
+                    }
+                    PDFViewer.SetMouseMode(MouseModes.PanTool);
+                    if (SnapToolEvent != null)
+                    {
+                        KeyValuePair<string, object> param = new KeyValuePair<string, object>("CloseSnap", null);
+                        SnapToolEvent.Invoke(this, param);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// 创建文件,路径为空时表示创建空白文档
+        /// 否则表示从图片路径创建PDf
+        /// </summary>
+        /// <param name="imagePath"></param>
+        /// <returns></returns>
+        public bool CreateFile(string imagePath = null)
+        {
+            string fileName = null;
+
+            saveToPDFViewer.CreateDocument();
+            if (saveToPDFViewer.Document == null)
+            {
+                AlertsMessage alertsMessage = new AlertsMessage();
+                alertsMessage.ShowDialog("", "创建文件失败.", "OK");
+                return false;
+            }
+
+            if (string.IsNullOrEmpty(imagePath))
+            {
+                fileName = "Blank Page.pdf";
+                //默认插入595*842 大小的页面
+                saveToPDFViewer.Document.InsertPage(0, 595, 842, null);
+            }
+            else
+            {
+                fileName = imagePath.Substring(imagePath.LastIndexOf("\\") + 1, imagePath.LastIndexOf(".") - imagePath.LastIndexOf("\\") - 1) + ".pdf";
+                Bitmap pic = new Bitmap(imagePath);
+                int width = pic.Size.Width;
+                int height = pic.Size.Height;
+
+                string ex = System.IO.Path.GetExtension(imagePath);
+                //其他格式或者名称中含空格的图片 在本地先转存一下
+                if ((ex != ".jpg" && ex != ".jpeg") || !Uri.IsWellFormedUriString(imagePath, UriKind.Absolute))
+                {
+                    //将其他格式图片转换成jpg
+                    string folderPath = Path.GetTempPath();
+                    if (File.Exists(folderPath))
+                    {
+                        File.Delete(folderPath);
+                    }
+                    DirectoryInfo tempfolder = new DirectoryInfo(folderPath);
+                    if (!tempfolder.Exists)
+                    {
+                        tempfolder.Create();
+                    }
+                    string targetPath = System.IO.Path.Combine(folderPath, Guid.NewGuid().ToString());
+                    imagePath = targetPath;
+                    pic.Save(targetPath, ImageFormat.Jpeg);
+                }
+                pic.Dispose();
+
+                var result = saveToPDFViewer.Document.InsertPage(0, width, height, imagePath);
+                if (!result)
+                {
+                    AlertsMessage alertsMessage = new AlertsMessage();
+                    alertsMessage.ShowDialog("", "创建文件失败.", "OK");
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// 保存WriteableBitmap图像
+        /// </summary>
+        /// <param name="wtbBmp"></param>
+        private string SaveImage(WriteableBitmap wtbBmp)
+        {
+            string isSave = null;
+            if (wtbBmp == null)
+            {
+                return isSave;
+            }
+            try
+            {
+                DirectoryInfo tempfolder = new DirectoryInfo(Path.Combine(App.CurrentPath, "Temp"));
+                string strpath = tempfolder + DateTime.Now.ToString("yyyyMMddfff") + ".jpg";
+                if (!File.Exists(tempfolder.FullName))
+                {
+                    Directory.CreateDirectory(tempfolder.FullName);
+                }
+
+                using (FileStream stream = new FileStream(strpath, FileMode.Create))
+                {
+                    JpegBitmapEncoder bitmapEncoder = new JpegBitmapEncoder();
+                    bitmapEncoder.Frames.Add(BitmapFrame.Create(wtbBmp));
+                    bitmapEncoder.Save(stream);
+                    isSave = strpath;
+                }
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine(ex.ToString());
+                isSave = null;
+            }
+            return isSave;
+        }
+
+        /// <summary>
+        /// 复制
+        /// </summary>
+        private void SnapCopyEvent()
+        {
+            if (SnapToolArgs != null)
+            {
+                WriteableBitmap saveBitmap = SnapToolArgs.GetSnapshotImage();
+                if (saveBitmap != null)
+                {
+                    Bitmap bitmap = BitmapFromWriteableBitmap(saveBitmap);
+                    Clipboard.SetImage(ChangeBitmapToBitmapSource(bitmap));
+                    PDFViewer.SetMouseMode(MouseModes.PanTool);
+                    if (SnapToolEvent != null)
+                    {
+                        KeyValuePair<string, object> param = new KeyValuePair<string, object>("CloseSnap", null);
+                        SnapToolEvent.Invoke(this, param);
+                    }
+                }
+            }
+        }
+
+        private System.Drawing.Bitmap BitmapFromWriteableBitmap(WriteableBitmap writeBmp)
+        {
+            System.Drawing.Bitmap bmp;
+            using (MemoryStream outStream = new MemoryStream())
+            {
+                BitmapEncoder enc = new BmpBitmapEncoder();
+                enc.Frames.Add(BitmapFrame.Create((BitmapSource)writeBmp));
+                enc.Save(outStream);
+                bmp = new System.Drawing.Bitmap(outStream);
+            }
+            return bmp;
+        }
+
+        /// <summary>
+        /// 从Bitmap转换成BitmapSource
+        /// </summary>
+        /// <param name="bmp"></param>
+        /// <returns></returns>
+        public BitmapSource ChangeBitmapToBitmapSource(Bitmap bmp)
+        {
+            BitmapSource returnSource;
+            try
+            {
+                returnSource = Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
+            }
+            catch
+            {
+                returnSource = null;
+            }
+            return returnSource;
+        }
+    }
+}

+ 27 - 2
PDF Office/ViewModels/Tools/AnnotToolContentViewModel.Function.cs

@@ -7,6 +7,7 @@ using PDF_Office.CustomControl;
 using PDF_Office.Helper;
 using PDF_Office.Properties;
 using PDF_Office.ViewModels.PropertyPanel.AnnotPanel;
+using PDF_Office.Views.PropertyPanel.AnnotPanel;
 using PDFSettings;
 using Prism.Mvvm;
 using Prism.Regions;
@@ -16,6 +17,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
+using System.Windows.Controls;
 using System.Windows.Media;
 
 namespace PDF_Office.ViewModels.Tools
@@ -173,7 +175,7 @@ namespace PDF_Office.ViewModels.Tools
                 linkArgs.LinkType = LINK_TYPE.GOTO;
                 linkArgs.DestIndex = -1;
             }
-            
+
             annotAttribsList[AnnotAttrib.LinkType] = linkArgs.LinkType;
             annotAttribsList[AnnotAttrib.LinkUri] = linkArgs.URI;
             annotAttribsList[AnnotAttrib.LinkDestIndx] = linkArgs.DestIndex;
@@ -605,6 +607,28 @@ namespace PDF_Office.ViewModels.Tools
             return stampArgs;
         }
 
+        private AnnotHandlerEventArgs GetSnapshotEdit(CustomIconToggleBtn annotBtn)
+        {
+            SnapshotEditToolArgs snapshotArgs = new SnapshotEditToolArgs();
+
+            snapshotArgs.ControlPointColor = Colors.White;
+            snapshotArgs.BgColor = Color.FromArgb(0x99, 0x00, 0x00, 0x00);
+            snapshotArgs.LineColor = Color.FromArgb(0xFF, 0x47, 0x7E, 0xDE);
+
+            #region to do
+
+            //SnapshotEditMenu snapMenu = new SnapshotEditMenu();
+            //snapshotArgs.ToolPanel = snapMenu;
+            //SnapshotEditMenuViewModel snapshotEditMenuViewModel = (SnapshotEditMenuViewModel)snapMenu.DataContext;
+            //snapshotEditMenuViewModel.SnapToolArgs = snapshotArgs;
+            //snapshotEditMenuViewModel.PdfViewer = PDFViewer;
+            //snapshotEditMenuViewModel.ToggleBtn = annotBtn;
+
+            #endregion to do
+
+            return snapshotArgs;
+        }
+
         /// <summary>
         /// 导航到同一个注释xaml时,需要区分某个注释;比如高亮、删除线、下划线
         /// </summary>
@@ -625,7 +649,6 @@ namespace PDF_Office.ViewModels.Tools
             if (annot != null)
                 propertyPanel.annot = annot;
 
-           
             if (annotAttribsList != null)
             {
                 propertyPanel.AnnotEvent = AnnotAttribEvent.GetAnnotAttribEvent(annot, annotAttribsList);
@@ -636,7 +659,9 @@ namespace PDF_Office.ViewModels.Tools
             }
 
             if (string.IsNullOrEmpty(viewContent) == false)
+            {
                 viewContentViewModel.SelectedPrpoertyPanel(viewContent, propertyPanel);
+            }
         }
 
         #endregion 注释工具

文件差异内容过多而无法显示
+ 599 - 474
PDF Office/ViewModels/Tools/AnnotToolContentViewModel.cs


+ 12 - 8
PDF Office/Views/BOTA/AnnotationContent.xaml

@@ -217,6 +217,8 @@
                     Width="40"
                     Margin="0,0,10,0"
                     HorizontalAlignment="Right"
+                    Click="BtnMore_Click"
+                    Initialized="BtnMore_Initialized"
                     Style="{StaticResource PageEditToolBtn}">
                     <Path Data="M3 2C3 2.82843 2.32843 3.5 1.5 3.5C0.671573 3.5 0 2.82843 0 2C0 1.17157 0.671573 0.5 1.5 0.5C2.32843 0.5 3 1.17157 3 2ZM8.3999 2C8.3999 2.82843 7.72833 3.5 6.8999 3.5C6.07148 3.5 5.3999 2.82843 5.3999 2C5.3999 1.17157 6.07148 0.5 6.8999 0.5C7.72833 0.5 8.3999 1.17157 8.3999 2ZM12.5 3.5C13.3284 3.5 14 2.82843 14 2C14 1.17157 13.3284 0.5 12.5 0.5C11.6716 0.5 11 1.17157 11 2C11 2.82843 11.6716 3.5 12.5 3.5Z" Fill="{StaticResource path.fill}">
                         <Path.RenderTransform>
@@ -229,13 +231,12 @@
                         <ContextMenu
                             Name="MenuMore"
                             Width="auto"
-                            Style="{StaticResource ContextMenuStyle}">
-                            <ContextMenu.ItemContainerStyle>
-                                <Style TargetType="MenuItem">
-                                    <Setter Property="Padding" Value="-25,7,-35,7" />
-                                    <Setter Property="VerticalContentAlignment" Value="Center" />
-                                </Style>
-                            </ContextMenu.ItemContainerStyle>
+                            Placement="Bottom">
+                            <!--<ContextMenu.ItemContainerStyle>
+                            <Style TargetType="MenuItem">
+                            <Setter Property="Padding" Value="-25,7,-35,7" />
+                            </Style>
+                            </ContextMenu.ItemContainerStyle>-->
                             <MenuItem
                                 Name="MenuExpandAll"
                                 Width="auto"
@@ -253,7 +254,10 @@
                                 <MenuItem.Header>
                                     <TextBlock Name="MenuSortText" Text="排序" />
                                 </MenuItem.Header>
-                                <MenuItem Name="MenuPageSort" Command="{Binding PageSortCommand}">
+                                <MenuItem
+                                    Name="MenuPageSort"
+                                    Background="Red"
+                                    Command="{Binding PageSortCommand}">
                                     <!--<MenuItem.Icon>
                                     <Path
                                     HorizontalAlignment="Center"

+ 24 - 13
PDF Office/Views/BOTA/AnnotationContent.xaml.cs

@@ -130,19 +130,19 @@ namespace PDF_Office.Views.BOTA
         private void SetAllExpander(bool isexpand)
         {
             AnnotationList.Dispatcher.Invoke(() =>
-            {
-                //开启虚拟化之后 全部展开和折叠会有问题
-                var scroller = GetScrollHost(AnnotationList);
-                var stackpanel = CommonHelper.FindVisualChild<StackPanel>(scroller);
-                int count = VisualTreeHelper.GetChildrenCount(stackpanel);
-                for (int i = 0; i < count; i++)
-                {
-                    var item = VisualTreeHelper.GetChild(stackpanel, i) as GroupItem;
-                    var g = CommonHelper.FindVisualChild<Expander>(item);
-                    if (g != null)
-                        g.IsExpanded = isexpand;
-                }
-            });
+              {
+                  //开启虚拟化之后 全部展开和折叠会有问题
+                  var scroller = GetScrollHost(AnnotationList);
+                  var stackpanel = CommonHelper.FindVisualChild<StackPanel>(scroller);
+                  int count = VisualTreeHelper.GetChildrenCount(stackpanel);
+                  for (int i = 0; i < count; i++)
+                  {
+                      var item = VisualTreeHelper.GetChild(stackpanel, i) as GroupItem;
+                      var g = CommonHelper.FindVisualChild<Expander>(item);
+                      if (g != null)
+                          g.IsExpanded = isexpand;
+                  }
+              });
         }
 
         private ScrollViewer GetScrollHost(ListBox listBox)
@@ -239,5 +239,16 @@ namespace PDF_Office.Views.BOTA
                 viewModel.DeleteCommand.Execute(annotation);
             }
         }
+
+        private void BtnMore_Initialized(object sender, EventArgs e)
+        {
+            BtnMore.ContextMenu = null;
+        }
+
+        private void BtnMore_Click(object sender, RoutedEventArgs e)
+        {
+            MenuMore.PlacementTarget = BtnMore;
+            MenuMore.IsOpen = true;
+        }
     }
 }

+ 113 - 0
PDF Office/Views/PropertyPanel/AnnotPanel/SnapshotEditMenu.xaml

@@ -0,0 +1,113 @@
+<UserControl
+    x:Class="PDF_Office.Views.PropertyPanel.AnnotPanel.SnapshotEditMenu"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:AnnotPanel="clr-namespace:PDF_Office.ViewModels.PropertyPanel.AnnotPanel"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:local="clr-namespace:PDF_Office.Views.PropertyPanel.AnnotPanel"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:prism="http://prismlibrary.com/"
+    d:DataContext="{d:DesignInstance Type=AnnotPanel:SnapshotEditMenuViewModel}"
+    d:DesignHeight="450"
+    d:DesignWidth="800"
+    prism:ViewModelLocator.AutoWireViewModel="True"
+    Background="#FFF8F8F8"
+    mc:Ignorable="d">
+    <Grid>
+        <StackPanel Orientation="Vertical">
+            <Button
+                x:Name="BtnSnapCopy"
+                Height="40"
+                Padding="5"
+                HorizontalContentAlignment="Left"
+                Background="#FFF8F8F8"
+                BorderThickness="0"
+                Command="{Binding SnapCopyCommand}"
+                FontSize="14"
+                Tag="ReSnapCopy">
+                <Button.Content>
+                    复制
+                </Button.Content>
+            </Button>
+
+            <Button
+                x:Name="BtnSnapExport"
+                Height="40"
+                Padding="5"
+                HorizontalContentAlignment="Left"
+                Background="#FFF8F8F8"
+                BorderThickness="0"
+                Click="BtnSnapExport_Click"
+                FontSize="14"
+                Initialized="BtnSnapExport_Initialized"
+                Tag="SnapExport">
+                <Button.Content>
+                    <StackPanel Orientation="Horizontal">
+                        <TextBlock Width="160">导出</TextBlock>
+                        <Path
+                            Margin="0,0,0,0"
+                            Data="M7.56438 6.49996L3.59473 10.4696L4.65539 11.5303L9.15537 7.03029C9.44826 6.7374 9.44826 6.26252 9.15537 5.96963L4.65539 1.46964L3.59473 2.5303L7.56438 6.49996Z"
+                            Fill="#616469" />
+                    </StackPanel>
+                </Button.Content>
+                <Button.ContextMenu>
+                    <ContextMenu Name="MenuExport" Placement="Right">
+                        <MenuItem
+                            Name="MenuExportPNG"
+                            Command="{Binding ExportPNGCommand}"
+                            Header="PNG" />
+                        <MenuItem
+                            Name="MenuExportJPG"
+                            Command="{Binding ExportJPGCommand}"
+                            Header="JPG" />
+                        <MenuItem
+                            Name="MenuExportPDF"
+                            Command="{Binding ExportPDFCommand}"
+                            Header="PDF" />
+                    </ContextMenu>
+                </Button.ContextMenu>
+            </Button>
+            <Button
+                x:Name="BtnSnapCropping"
+                Height="40"
+                Padding="5"
+                HorizontalContentAlignment="Left"
+                Background="#FFF8F8F8"
+                BorderThickness="0"
+                Command="{Binding CroppingCommand}"
+                FontSize="14"
+                Tag="SnapCropping">
+                <Button.Content>
+                    裁剪
+                </Button.Content>
+            </Button>
+            <Button
+                x:Name="BtnSnapZoom"
+                Height="40"
+                Padding="5"
+                HorizontalContentAlignment="Left"
+                Background="#FFF8F8F8"
+                BorderThickness="0"
+                FontSize="14"
+                Tag="SnapZoom">
+                <Button.Content>
+                    缩放至所选区域
+                </Button.Content>
+            </Button>
+            <Button
+                x:Name="BtnSnapPrint"
+                Height="40"
+                Padding="5"
+                HorizontalContentAlignment="Left"
+                Background="#FFF8F8F8"
+                BorderThickness="0"
+                Command="{Binding PrintCommand}"
+                FontSize="14"
+                Tag="SnapPrint">
+                <Button.Content>
+                    打印
+                </Button.Content>
+            </Button>
+        </StackPanel>
+    </Grid>
+</UserControl>

+ 41 - 0
PDF Office/Views/PropertyPanel/AnnotPanel/SnapshotEditMenu.xaml.cs

@@ -0,0 +1,41 @@
+using ComPDFKitViewer.AnnotEvent;
+using ComPDFKitViewer.PdfViewer;
+using System;
+using System.Collections.Generic;
+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.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace PDF_Office.Views.PropertyPanel.AnnotPanel
+{
+    /// <summary>
+    /// SnapshotEditMenu.xaml 的交互逻辑
+    /// </summary>
+    public partial class SnapshotEditMenu : UserControl
+    {
+        public SnapshotEditMenu()
+        {
+            InitializeComponent();
+        }
+
+        private void BtnSnapExport_Click(object sender, RoutedEventArgs e)
+        {
+            MenuExport.PlacementTarget = BtnSnapExport;
+            MenuExport.IsOpen = true;
+        }
+
+        private void BtnSnapExport_Initialized(object sender, EventArgs e)
+        {
+            BtnSnapExport.ContextMenu = null;
+        }
+    }
+}

文件差异内容过多而无法显示
+ 62 - 68
PDF Office/Views/Tools/AnnotToolContent.xaml


+ 1 - 0
PDF Office/packages.config

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
+  <package id="BouncyCastle" version="1.8.9" targetFramework="net462" />
   <package id="Dropbox.Api" version="6.33.0" targetFramework="net462" />
   <package id="DryIoc.dll" version="4.7.7" targetFramework="net462" />
   <package id="Google.Apis" version="1.57.0" targetFramework="net462" />