Browse Source

compdfkit demo(windows) - 书签列表

liyuxuan 1 year ago
parent
commit
e78da15202

+ 19 - 0
compdfkit_demo_windows/compdfkit/compdfkit-tools/PDFView/PDFBookmark/PDFBookmarkControl/CPDFBookmarkControl.xaml

@@ -0,0 +1,19 @@
+<UserControl x:Class="compdfkit_tools.PDFControl.CPDFBookmarkControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:compdfkit_tools.PDFControl"
+             xmlns:ui="clr-namespace:compdfkit_tools.PDFControlUI"
+             xmlns:convert="clr-namespace:compdfkit_tools.Common"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800">
+    <Grid Margin="5">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="auto"></RowDefinition>
+            <RowDefinition Height="*"></RowDefinition>
+        </Grid.RowDefinitions>
+        <ui:CPDFBookmarkAddUI x:Name="BookmarkAddUI" Padding="5"></ui:CPDFBookmarkAddUI>
+        <ui:CPDFBookmarkResultUI Grid.Row="1" x:Name="BookmarkResultUI"></ui:CPDFBookmarkResultUI>
+    </Grid>
+</UserControl>

+ 175 - 0
compdfkit_demo_windows/compdfkit/compdfkit-tools/PDFView/PDFBookmark/PDFBookmarkControl/CPDFBookmarkControl.xaml.cs

@@ -0,0 +1,175 @@
+using ComPDFKit.PDFDocument;
+using compdfkit_tools.PDFControlUI;
+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 compdfkit_tools.PDFControl
+{
+    /// <summary>
+    /// CPDFBookmarkControl.xaml 的交互逻辑
+    /// </summary>
+    public partial class CPDFBookmarkControl : UserControl
+    {
+        /// <summary>
+        /// PDFViewer
+        /// </summary>
+        private CPDFViewer pdfView;
+
+        public CPDFBookmarkControl()
+        {
+            InitializeComponent();
+            Loaded += CPDFBookmarkControl_Loaded;
+        }
+
+        /// <summary>
+        /// 控件加载完成 初始化相应事件绑定
+        /// </summary>
+        private void CPDFBookmarkControl_Loaded(object sender, RoutedEventArgs e)
+        {
+            BookmarkAddUI.BookmarkAddEvent += BookmarkAddUI_BookmarkAddEvent;
+            BookmarkResultUI.SelectionChanged += BookmarkResultUI_SelectionChanged;
+            BookmarkResultUI.BookmarkChanged += BookmarkResultUI_BookmarkChanged;
+            BookmarkResultUI.BookmarkDelete += BookmarkResultUI_BookmarkDelete;
+            BookmarkResultUI.BookmarkClicked += BookmarkResultUI_BookmarkClicked;
+        }
+
+        /// <summary>
+        /// 书签列表点击 跳转到书签页面
+        /// </summary>
+        private void BookmarkResultUI_BookmarkClicked(object sender, int e)
+        {
+            GotoBookmarkPage(e);
+        }
+
+        /// <summary>
+        /// 书签删除
+        /// </summary>
+        private void BookmarkResultUI_BookmarkDelete(object sender, BookmarkChangeData e)
+        {
+            if (pdfView == null || pdfView.Document == null)
+            {
+                return;
+            }
+
+            pdfView.Document.RemoveBookmark(e.PageIndex);
+        }
+
+        /// <summary>
+        /// 书签更改
+        /// </summary>
+        private void BookmarkResultUI_BookmarkChanged(object sender, BookmarkChangeData e)
+        {
+            if (pdfView == null || pdfView.Document == null)
+            {
+                return;
+            }
+            pdfView.Document.EditBookmark(e.PageIndex, e.NewTitle);
+        }
+
+        /// <summary>
+        /// 书签列表选中 跳转到书签页面
+        /// </summary>
+        private void BookmarkResultUI_SelectionChanged(object sender, int e)
+        {
+            if (e >= 0)
+            {
+                BindBookmarkResult bindResult = BookmarkResultUI.GetItem(e);
+                if (bindResult != null)
+                {
+                    GotoBookmarkPage(bindResult.PageIndex);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 添加书签
+        /// </summary>
+        private void BookmarkAddUI_BookmarkAddEvent(object sender, string e)
+        {
+            if (pdfView == null || pdfView.Document == null)
+            {
+                return;
+            }
+
+            if (!string.IsNullOrEmpty(e))
+            {
+                int pageIndex = Math.Max(0, pdfView.CurrentIndex);
+                bool addState= pdfView.Document.AddBookmark(new CPDFBookmark()
+                {
+                    PageIndex = pageIndex,
+                    Title = e,
+                });
+
+                if(addState)
+                {
+                    LoadBookmark();
+                }
+            }
+        }
+
+        /// <summary>
+        /// 跳转书签页面
+        /// </summary>
+        private void GotoBookmarkPage(int pageIndex)
+        {
+            if (pdfView == null || pdfView.Document == null)
+            {
+                return;
+            }
+
+            if (pageIndex >= 0)
+            {
+                pdfView.GoToPage(pageIndex);
+            }
+        }
+
+        /// <summary>
+        /// 设置PDFViewer
+        /// </summary>
+        public void SetPDFView(CPDFViewer newPDFView)
+        {
+            pdfView = newPDFView;
+        }
+
+        /// <summary>
+        /// 加载书签列表
+        /// </summary>
+        public void LoadBookmark()
+        {
+            if (pdfView == null || pdfView.Document == null)
+            {
+                return;
+            }
+
+            List<CPDFBookmark> bookmarkList = pdfView.Document.GetBookmarkList();
+            List<BindBookmarkResult> bindBookmarkList = new List<BindBookmarkResult>();
+            if (bookmarkList != null && bookmarkList.Count>0)
+            {
+               
+                foreach (CPDFBookmark bookmark in bookmarkList.AsEnumerable().OrderBy(x=>x.PageIndex))
+                {
+                    bindBookmarkList.Add(new BindBookmarkResult()
+                    {
+                        PageIndex=bookmark.PageIndex,
+                        BookmarkTitle=bookmark.Title
+                    });
+                }
+               
+            }
+            BookmarkResultUI?.SetBookmarkResult(bindBookmarkList);
+        }
+    }
+}

+ 61 - 0
compdfkit_demo_windows/compdfkit/compdfkit-tools/PDFView/PDFBookmark/PDFBookmarkUI/CPDFBookmarkAddUI.xaml

@@ -0,0 +1,61 @@
+<UserControl x:Class="compdfkit_tools.PDFControlUI.CPDFBookmarkAddUI"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:compdfkit_tools.PDFControlUI"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800">
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <local:BoolEnableConvert x:Key="BoolEnableCovert"/>
+        </ResourceDictionary>
+    </UserControl.Resources>
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="auto"></RowDefinition>
+            <RowDefinition Height="auto"></RowDefinition>
+        </Grid.RowDefinitions>
+        
+        <Grid>
+            <Border CornerRadius="20" BorderThickness="0" Width="140" Height="35" Background="#E6E6E6" ClipToBounds="True" 
+                    HorizontalAlignment="Right" Margin="0,0,10,0" MouseLeftButtonDown="Border_MouseLeftButtonDown">
+                <Grid>
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="*"></ColumnDefinition>
+                        <ColumnDefinition Width="auto"></ColumnDefinition>
+                    </Grid.ColumnDefinitions>
+                    <Viewbox Width="25" HorizontalAlignment="Right" Margin="0,0,10,0">
+                        <Path Fill="#8A8A8A" >
+                            <Path.Data>
+                                M13.5 7.99997C13.5 11.0375 11.0376 13.5 8 13.5C4.96243 13.5 2.5 11.0375 2.5 7.99997C2.5 4.9624 4.96243 
+                            2.49997 8 2.49997C11.0376 2.49997 13.5 4.9624 13.5 7.99997ZM15 7.99997C15 11.866 11.866 15 8 15C4.13401 
+                            15 1 11.866 1 7.99997C1 4.13398 4.13401 0.999969 8 0.999969C11.866 0.999969 15 4.13398 15 7.99997ZM7.25005 
+                            4.8V7.25H4.80005V8.75H7.25005V11.2H8.75005V8.75H11.2V7.25H8.75005V4.8H7.25005Z
+                            </Path.Data>
+                        </Path>
+                    </Viewbox>
+
+                    <TextBlock Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,10,0">Add Bookmark</TextBlock>
+                </Grid>
+            </Border>
+        </Grid>
+
+        <Border Name="BookmarkInputPanel" Grid.Row="1" CornerRadius="5" Background="#E2E3E6" Padding="5" Margin="0,5,0,0" Visibility="Collapsed">
+            <Grid >
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                </Grid.RowDefinitions>
+                <TextBlock Name="PageNumText"></TextBlock>
+                <TextBox Name="BookmarkText" Grid.Row="1" Height="30" VerticalContentAlignment="Center"></TextBox>
+                <StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Right" Margin="0,10,0,0">
+                    <Button Padding="5" Width="60" Click="ButtonCancel_Click">Cancel</Button>
+                    <Button Margin="10,0,0,0" Padding="5" Width="60" Click="ButtonAdd_Click"
+                            IsEnabled="{Binding ElementName=BookmarkText,Path=Text,Converter={StaticResource BoolEnableCovert}}">Add</Button>
+                </StackPanel>
+            </Grid>
+        </Border>
+    </Grid>
+</UserControl>

+ 98 - 0
compdfkit_demo_windows/compdfkit/compdfkit-tools/PDFView/PDFBookmark/PDFBookmarkUI/CPDFBookmarkAddUI.xaml.cs

@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+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 compdfkit_tools.PDFControlUI
+{
+    public partial class CPDFBookmarkAddUI : UserControl
+    {
+        /// <summary>
+        /// 书签添加按钮点击通知
+        /// </summary>
+        public event EventHandler<string> BookmarkAddEvent;
+
+        private bool toggleState;
+        public CPDFBookmarkAddUI()
+        {
+            InitializeComponent();
+        }
+
+        /// <summary>
+        /// 书签添加界面切换显示添加输入界面
+        /// </summary>
+        private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            toggleState = !toggleState;
+            BookmarkInputPanel.Visibility=toggleState?Visibility.Visible:Visibility.Collapsed;
+        }
+
+        /// <summary>
+        /// 取消添加 隐藏 添加界面
+        /// </summary>
+        private void ButtonCancel_Click(object sender, RoutedEventArgs e)
+        {
+            toggleState = false;
+            BookmarkInputPanel.Visibility = Visibility.Collapsed;
+        }
+
+        /// <summary>
+        /// 书签添加按钮点击 触发添加通知
+        /// </summary>
+        private void ButtonAdd_Click(object sender, RoutedEventArgs e)
+        {
+            if(!string.IsNullOrEmpty(BookmarkText.Text))
+            {
+                BookmarkAddEvent?.Invoke(this, BookmarkText.Text);
+                BookmarkText.Text = string.Empty;
+            }
+        }
+    }
+
+    internal class BoolEnableConvert : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null)
+            {
+                return false;
+            }
+            else
+            {
+                try
+                {
+                    if (value is string)
+                    {
+                       string checkValue=value as string;
+                        if(checkValue.Length>0)
+                        {
+                            return true;
+                        }
+                    }
+                   
+                }
+                catch(Exception ex)
+                {
+
+                }
+                return false;
+            }
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 90 - 0
compdfkit_demo_windows/compdfkit/compdfkit-tools/PDFView/PDFBookmark/PDFBookmarkUI/CPDFBookmarkResultUI.xaml

@@ -0,0 +1,90 @@
+<UserControl x:Class="compdfkit_tools.PDFControlUI.CPDFBookmarkResultUI"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:compdfkit_tools.PDFControlUI"
+             xmlns:convert="clr-namespace:compdfkit_tools.Common"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800">
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <convert:ListViewWidthConvert x:Key="ListViewWidthConvert"/>
+        </ResourceDictionary>
+    </UserControl.Resources>
+    <Grid>
+        <ListView Name="ResultListControl" VirtualizingPanel.IsVirtualizingWhenGrouping="True" SelectionChanged="ResultListControl_SelectionChanged"
+                  ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderThickness="0" SelectionMode="Single" MouseLeftButtonDown="ResultListControl_MouseLeftButtonDown">
+            <ListView.GroupStyle>
+                <GroupStyle>
+                    <GroupStyle.HeaderTemplate>
+                        <DataTemplate>
+                            <StackPanel Background="#E2E3E6" Height="30" Orientation="Horizontal">
+                                
+                                <TextBlock Padding="12,4,0,4" FontWeight="SemiBold" FontSize="12"  
+                                           FontFamily="Segoe UI" Foreground="#666666 ">Page</TextBlock>
+                                <TextBlock  HorizontalAlignment="Left" Padding="10,4,0,4"
+                                           FontWeight="SemiBold" FontSize="12"  FontFamily="Segoe UI" Foreground="#666666 " Text="{Binding Name}">
+                                </TextBlock>
+                                
+                            </StackPanel>
+                        </DataTemplate>
+                    </GroupStyle.HeaderTemplate>
+                    <GroupStyle.Panel>
+                        <ItemsPanelTemplate>
+                            <VirtualizingStackPanel/>
+                        </ItemsPanelTemplate>
+                    </GroupStyle.Panel>
+                </GroupStyle>
+            </ListView.GroupStyle>
+
+            <ListView.ItemsPanel>
+                <ItemsPanelTemplate>
+                    <VirtualizingStackPanel Background="White" Margin="-5,0,0,0"></VirtualizingStackPanel>
+                </ItemsPanelTemplate>
+            </ListView.ItemsPanel>
+
+            <ListView.ItemTemplate>
+                <ItemContainerTemplate>
+                    <Grid Background="#01FFFFFF" Width="{Binding ElementName=ResultListControl,Path=ActualWidth,Converter={StaticResource ListViewWidthConvert}}" MinHeight="30" 
+                          MouseEnter="Grid_MouseEnter" MouseLeave="Grid_MouseLeave" Tag="{Binding}" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
+                       
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="*"></ColumnDefinition>
+                            <ColumnDefinition Width="auto"></ColumnDefinition>
+                        </Grid.ColumnDefinitions>
+                        
+                        <TextBox MinHeight="20" VerticalAlignment="Center" Margin="2,0,5,0" IsReadOnly="True" BorderThickness="0" IsHitTestVisible="False"
+                                 AcceptsReturn="True" Background="Transparent" Text="{Binding BindProperty.BookmarkTitle}"></TextBox>
+
+                        <Border CornerRadius="5" VerticalAlignment="Center" Background="#E6E6E6" Grid.Column="1" Padding="10,5,10,5" Visibility="Collapsed">
+                            <StackPanel Orientation="Horizontal">
+                                <Border MouseLeftButtonDown="EditBorder_Click" Background="#01FFFFFF">
+                                    <Viewbox Width="20" Height="20">
+                                        <Path Fill="#252629">
+                                            <Path.Data>
+                                                M3 2.5H7V1H3C1.89543 1 1 1.89543 1 3V13C1 14.1046 1.89543 15 3 15H13C14.1046 15 15 14.1046 15 13V9H13.5V13C13.5 13.2761 
+                                        13.2761 13.5 13 13.5H3C2.72386 13.5 2.5 13.2761 2.5 13V3C2.5 2.72386 2.72386 2.5 3 2.5ZM14.8987 2.29362L13.838 
+                                        1.23296L5.9999 9.07108L7.06056 10.1317L14.8987 2.29362Z
+                                            </Path.Data>
+                                        </Path>
+                                    </Viewbox>
+                                </Border>
+
+                                <Border MouseLeftButtonDown="DelBorder_Click"  Background="#01FFFFFF">
+                                    <Viewbox Margin="10,0,0,0" Width="20" Height="20">
+                                        <Path Fill="#252629">
+                                            <Path.Data>
+                                                M8 2H12V0H8V2ZM17 5H19V3H15H5H1V5H3V18C3 19.1046 3.89543 20 5 20H15C16.1046 20 17 19.1046 17 18V5ZM15 5H5V18H15V5ZM9 15L9 8H11V15H9Z
+                                            </Path.Data>
+                                        </Path>
+                                    </Viewbox>
+                                </Border>
+                            </StackPanel>
+                        </Border>
+                    </Grid>
+                </ItemContainerTemplate>
+            </ListView.ItemTemplate>
+        </ListView>
+    </Grid>
+</UserControl>

+ 360 - 0
compdfkit_demo_windows/compdfkit/compdfkit-tools/PDFView/PDFBookmark/PDFBookmarkUI/CPDFBookmarkResultUI.xaml.cs

@@ -0,0 +1,360 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+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 compdfkit_tools.PDFControlUI
+{ 
+    public partial class CPDFBookmarkResultUI : UserControl
+    {
+        /// <summary>
+        /// 书签列表点击选中更改事件
+        /// </summary>
+        public event EventHandler<int> SelectionChanged;
+
+        /// <summary>
+        /// 搜索结果列表点击选中事件
+        /// </summary>
+        public event EventHandler<BookmarkChangeData> BookmarkChanged;
+
+        /// <summary>
+        /// 书签删除点击事件
+        /// </summary>
+        public event EventHandler<BookmarkChangeData> BookmarkDelete;
+
+        /// <summary>
+        /// 点击书签事件
+        /// </summary>
+        public event EventHandler<int> BookmarkClicked;
+
+        /// <summary>
+        /// 绑定书签结果集合
+        /// </summary>
+        private ObservableCollection<BookmarkBindData> bookmarkResults;
+
+        public CPDFBookmarkResultUI()
+        {
+            InitializeComponent();
+            bookmarkResults = new ObservableCollection<BookmarkBindData>();
+            ICollectionView groupView = CollectionViewSource.GetDefaultView(bookmarkResults);
+            groupView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(BookmarkBindData.ShowPageIndex)));
+        }
+
+        /// <summary>
+        /// 鼠标移入事件 用以控制展示右侧编辑删除面板
+        /// </summary>
+        private void Grid_MouseEnter(object sender, MouseEventArgs e)
+        {
+            Grid sourceGrid=sender as Grid;
+            if(sourceGrid!=null && sourceGrid.Children.Count==2)
+            {
+                Border sourceBorder = sourceGrid.Children[1] as Border;
+                if(sourceBorder!=null)
+                {
+                    sourceBorder.Visibility = Visibility.Visible;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 鼠标移出事件 用以控制隐藏右侧编辑 删除面板
+        /// </summary>
+        private void Grid_MouseLeave(object sender, MouseEventArgs e)
+        {
+            Grid sourceGrid = sender as Grid;
+            if (sourceGrid != null && sourceGrid.Children.Count == 2)
+            {
+                Border sourceBorder = sourceGrid.Children[1] as Border;
+                if (sourceBorder != null)
+                {
+                    sourceBorder.Visibility = Visibility.Collapsed;
+                }
+                TextBox sourceTextBox = sourceGrid.Children[0] as TextBox;
+                if (sourceTextBox != null)
+                {
+                    sourceTextBox.IsReadOnly = true;
+                    sourceTextBox.BorderThickness = new Thickness(0);
+                    sourceTextBox.IsHitTestVisible = false;
+
+                    BookmarkBindData bindData=sourceGrid.Tag as BookmarkBindData;
+                    if (bindData!=null && IsBookmarkChanged(bindData,sourceTextBox.Text))
+                    {
+                        BookmarkChanged?.Invoke(this, new BookmarkChangeData()
+                        {
+                            PageIndex=bindData.BindProperty.PageIndex,
+                            BookmarkTitle=bindData.BindProperty.BookmarkTitle,
+                            NewTitle=sourceTextBox.Text
+                        });
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// 编辑按钮点击事件 启用书签文本编辑
+        /// </summary>
+        private void EditBorder_Click(object sender, RoutedEventArgs e)
+        {
+            Border sourceBtn =sender as Border;
+            if(sourceBtn != null)
+            {
+                DependencyObject findElement = null;
+                if (FindParent<Grid>(sourceBtn, out findElement) && findElement != null)
+                {
+                    Grid sourceGrid = findElement as Grid;
+                    if (sourceGrid != null && sourceGrid.Children.Count == 2)
+                    {
+                        TextBox sourceTextBox = sourceGrid.Children[0] as TextBox;
+                        if (sourceTextBox != null)
+                        {
+                            sourceTextBox.IsReadOnly=false;
+                            sourceTextBox.IsHitTestVisible = true;
+                            sourceTextBox.BorderThickness=new Thickness(1);
+                        }
+                    }
+                }
+            }
+            e.Handled = true;
+        }
+
+        /// <summary>
+        /// 删除按钮点击事件 触发删除事件通知
+        /// </summary>
+        private void DelBorder_Click(object sender, RoutedEventArgs e)
+        {
+            Border sourceBtn = sender as Border;
+            if (sourceBtn != null)
+            {
+                DependencyObject findElement = null;
+                if (FindParent<Grid>(sourceBtn, out findElement) && findElement != null)
+                {
+                    Grid sourceGrid = findElement as Grid;
+                    BookmarkBindData bindData = sourceGrid.Tag as BookmarkBindData;
+                    if (bindData != null)
+                    {
+                        BookmarkDelete?.Invoke(this, new BookmarkChangeData()
+                        {
+                            PageIndex = bindData.BindProperty.PageIndex,
+                            BookmarkTitle = bindData.BindProperty.BookmarkTitle
+                        });
+                        bookmarkResults?.Remove(bindData);
+                    }
+                }
+            }
+            e.Handled = true;
+        }
+
+        /// <summary>
+        /// 递归查询指定类型的父节点元素
+        /// </summary>
+        /// <typeparam name="T">父元素节点类型</typeparam>
+        /// <param name="checkElement">要查找的元素</param>
+        /// <param name="parent">查找到的父节点元素</param>
+        /// <returns>查找到对应类型父节点元素则为true</returns>
+        private bool FindParent<T>(DependencyObject checkElement,out DependencyObject parent)
+        {
+            parent = null;
+
+            try
+            {
+                if (checkElement != null)
+                {
+                   DependencyObject parentElement=  VisualTreeHelper.GetParent(checkElement);
+                    if(parentElement!=null && parentElement is T)
+                    {
+                        parent =parentElement;
+                        return true;
+                    }
+                   return FindParent<T>(parentElement,out parent);
+                }
+            }
+            catch (Exception ex)
+            {
+
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// 判断书签文本是否更改
+        /// </summary>
+        private bool IsBookmarkChanged(BookmarkBindData bindData,string newTitle)
+        {
+            if(bindData!=null &&bindData.BindProperty!=null)
+            {
+                return bindData.BindProperty.BookmarkTitle != newTitle;
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// 将书签列表绑定到UI控件
+        /// </summary>
+        public void SetBookmarkResult(List<BindBookmarkResult> results)
+        {
+            bookmarkResults?.Clear();
+            if (results == null || results.Count == 0)
+            {
+                ResultListControl.ItemsSource = null;
+                return;
+            }
+
+            foreach (BindBookmarkResult item in results)
+            {
+                bookmarkResults.Add(new BookmarkBindData()
+                {
+                    BindProperty = item
+                });
+            }
+            ResultListControl.ItemsSource = bookmarkResults;
+        }
+
+        /// <summary>
+        /// 获取选中书签结果
+        /// </summary>
+        /// <returns>搜索结果</returns>
+        public BindBookmarkResult GetSelectItem()
+        {
+            BookmarkBindData bindData = ResultListControl.SelectedItem as BookmarkBindData;
+            if (bindData != null)
+            {
+                return bindData.BindProperty;
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// 获取指定索引书签对象
+        /// </summary>
+        /// <param name="index">指定索引</param>
+        /// <returns></returns>
+        public BindBookmarkResult GetItem(int index)
+        {
+            if (index < 0)
+            {
+                return null;
+            }
+            if (ResultListControl.HasItems && ResultListControl.Items.Count > index)
+            {
+                BookmarkBindData bindData = ResultListControl.Items[index] as BookmarkBindData;
+                if (bindData != null)
+                {
+                    return bindData.BindProperty;
+                }
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// 清除选中结果
+        /// </summary>
+        public void ClearSelection()
+        {
+            int oldSelectionIndex = ResultListControl.SelectedIndex;
+            ResultListControl.UnselectAll();
+            if (oldSelectionIndex != ResultListControl.SelectedIndex)
+            {
+                SelectionChanged?.Invoke(this,ResultListControl.SelectedIndex);
+            }
+        }
+
+        /// <summary>
+        /// 设置选中结果
+        /// </summary>
+        /// <param name="selectIndex">选中索引</param>
+        public void SelectItem(int selectIndex)
+        {
+            if (ResultListControl.SelectedIndex != selectIndex)
+            {
+                ResultListControl.SelectedIndex = selectIndex;
+            }
+        }
+
+        /// <summary>
+        /// 书签列表选中改变事件
+        /// </summary>
+        private void ResultListControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            SelectionChanged?.Invoke(this, ResultListControl.SelectedIndex);
+        }
+
+        /// <summary>
+        /// 书签列表点击书签事件
+        /// </summary>
+        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            Grid sourceGrid = sender as Grid;
+            if (sourceGrid != null)
+            {
+                BookmarkBindData bindData = sourceGrid.Tag as BookmarkBindData;
+                if (bindData != null)
+                {
+                    BookmarkClicked?.Invoke(this, bindData.BindProperty.PageIndex);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 点击空白清除选中项
+        /// </summary>
+        private void ResultListControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            ResultListControl?.UnselectAll();
+        }
+    }
+
+    public class BookmarkChangeData
+    {
+        /// <summary>
+        /// 页面索引
+        /// </summary>
+        public int PageIndex { get; set; }
+        /// <summary>
+        /// 原书签标题
+        /// </summary>
+        public string BookmarkTitle { get; set; }
+        /// <summary>
+        /// 修改后的标题
+        /// </summary>
+        public string NewTitle { get;set; }
+    }
+
+    public class BindBookmarkResult
+    {
+        /// <summary>
+        /// 页面索引
+        /// </summary>
+        public int PageIndex { get; set; }
+        /// <summary>
+        /// 书签标题
+        /// </summary>
+        public string BookmarkTitle { get; set; }
+    }
+
+    internal class BookmarkBindData
+    {
+        public int ShowPageIndex { get { return BindProperty.PageIndex + 1; } set { BindProperty.PageIndex = value; } }
+        public BindBookmarkResult BindProperty { get; set; }
+        public BookmarkBindData()
+        {
+            BindProperty = new BindBookmarkResult();
+        }
+    }
+}

+ 21 - 0
compdfkit_demo_windows/compdfkit/compdfkit-tools/compdfkit-tools.csproj

@@ -70,6 +70,15 @@
     </Compile>
     <Compile Include="Common\Convert\ListViewWidthConvert.cs" />
     <Compile Include="Helper\CommonHelper.cs" />
+    <Compile Include="PDFView\PDFBookmark\PDFBookmarkControl\CPDFBookmarkControl.xaml.cs">
+      <DependentUpon>CPDFBookmarkControl.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="PDFView\PDFBookmark\PDFBookmarkUI\CPDFBookmarkAddUI.xaml.cs">
+      <DependentUpon>CPDFBookmarkAddUI.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="PDFView\PDFBookmark\PDFBookmarkUI\CPDFBookmarkResultUI.xaml.cs">
+      <DependentUpon>CPDFBookmarkResultUI.xaml</DependentUpon>
+    </Compile>
     <Compile Include="PDFView\PDFDisplaySettings\PDFDisplaySettingsControl\CPDFBrowseModeControl.xaml.cs">
       <DependentUpon>CPDFBrowseModeControl.xaml</DependentUpon>
     </Compile>
@@ -163,6 +172,18 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="PDFView\PDFBookmark\PDFBookmarkControl\CPDFBookmarkControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="PDFView\PDFBookmark\PDFBookmarkUI\CPDFBookmarkAddUI.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="PDFView\PDFBookmark\PDFBookmarkUI\CPDFBookmarkResultUI.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="PDFView\PDFSearch\PDFSearchUI\CPDFSearchInputUI.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 13 - 0
compdfkit_demo_windows/compdfkit/viewer-ctrl-demo/MainWindow.xaml

@@ -61,6 +61,19 @@
                         </Path>
                     </ToggleButton.Content>
                 </ToggleButton>
+                
+                <!--书签-->
+                <ToggleButton Name="BookmarkToolButton"  Height="40"  Padding="0,5,0,5" BorderThickness="0" Background="{StaticResource color.bg.jumpbar}" Click="BookmarkToolButtonn_Click">
+                    <ToggleButton.Content>
+                        <Path Width="20" Height="20" Fill="#273C62">
+                            <Path.Data>
+                                M11.3793 12.8851C10.6069 12.1494 9.3931 12.1494 8.62069 12.8851L5 16.3333V3H15V16.3333L11.3793 12.8851ZM15.3103 19.3908L10 14.3333L4.68966 
+                                19.3908C4.053 19.9971 3 19.5459 3 18.6667V3C3 1.89543 3.89543 1 5 1H15C16.1046 1 17 1.89543 17 3V18.6667C17 19.5459 15.947 19.9971 
+                                15.3103 19.3908ZM7 5H8H12H13V6V7H12H8H7V6V5Z
+                            </Path.Data>
+                        </Path>
+                    </ToggleButton.Content>
+                </ToggleButton>
             </StackPanel>
 
             <!--工具栏展开-->

+ 29 - 18
compdfkit_demo_windows/compdfkit/viewer-ctrl-demo/MainWindow.xaml.cs

@@ -1,25 +1,9 @@
-using ComPDFKit.PDFDocument;
-using compdfkit_tools;
-using compdfkit_tools.PDFControl;
-using compdfkit_tools.PDFControl;
+using compdfkit_tools.PDFControl;
 using compdfkit_tools.PDFControlUI;
 using ComPDFKitViewer.PdfViewer;
-using Microsoft.Win32;
-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.Controls.Primitives;
-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 viewer_ctrl_demo
 {
@@ -61,6 +45,12 @@ namespace viewer_ctrl_demo
                 ((CPDFThumbnailControl)currentBotaTool).ThumbLoaded = false;
                 ((CPDFThumbnailControl)currentBotaTool).LoadThumb();
             }
+
+            if (currentBotaTool is CPDFBookmarkControl)
+            {
+                ((CPDFBookmarkControl)currentBotaTool).SetPDFView(pdfViewer);
+                ((CPDFBookmarkControl)currentBotaTool).LoadBookmark();
+            }
         }
 
         private void LoadDefaultDocument()
@@ -135,6 +125,27 @@ namespace viewer_ctrl_demo
             ClearToolState(ThumbToolButton);
         }
 
+        /// <summary>
+        /// 书签列表点击处理
+        /// </summary>
+        private void BookmarkToolButtonn_Click(object sender, RoutedEventArgs e)
+        {
+            UIElement botaTool = GetBotaTool();
+            if (botaTool == null || !(botaTool is CPDFBookmarkControl))
+            {
+                CPDFBookmarkControl bookmarkControl = new CPDFBookmarkControl();
+
+                if (pdfViewer != null && pdfViewer.Document != null)
+                {
+                    bookmarkControl.SetPDFView(pdfViewer);
+                    bookmarkControl.LoadBookmark();
+                }
+                SetBotaTool(bookmarkControl);
+            }
+            ExpandTool(BookmarkToolButton.IsChecked == true);
+            ClearToolState(BookmarkToolButton);
+        }
+
         /// <summary>
         /// 大纲列表处理
         /// </summary>
@@ -178,7 +189,7 @@ namespace viewer_ctrl_demo
         /// <param name="isExpand"></param>
         private void ExpandTool(bool isExpand)
         {
-            BotaToolContainer.Width = isExpand ? 200 : 0;
+            BotaToolContainer.Width = isExpand ? 300 : 0;
             BotaToolContainer.Visibility = isExpand ? Visibility.Visible : Visibility.Collapsed;
         }