Explorar el Código

BOTA大纲-初版UI交互部分

zhuyi hace 2 años
padre
commit
62bd24dc49

+ 1 - 0
PDF Office/App.xaml

@@ -15,6 +15,7 @@
                 <ResourceDictionary Source="pack://application:,,,/PDF Office;component/Styles/WindowsStyle.xaml" />
                 <ResourceDictionary Source="pack://application:,,,/PDF Office;component/Styles/CustomBtnStyle.xaml" />
                 <ResourceDictionary Source="pack://application:,,,/PDF Office;component/Styles/ContainerStyles/ComboxStyle/ComboxItemStyle.xaml" />
+                <ResourceDictionary Source="pack://application:,,,/PDF Office;component/Styles/PathButtonStyle.xaml"/>
                 <!--  Enable show customctrol's correctly UI in Xaml Designer  -->
                 <ResourceDictionary Source="pack://application:,,,/PDF Office;component/Themes/Generic.xaml" />
             </ResourceDictionary.MergedDictionaries>

+ 1 - 0
PDF Office/App.xaml.cs

@@ -129,6 +129,7 @@ namespace PDF_Office
             containerRegistry.RegisterForNavigation<ToolsBarContent>();
             containerRegistry.RegisterForNavigation<AnnotToolContent>();
             containerRegistry.RegisterForNavigation<BookmarkContent>();
+            containerRegistry.RegisterForNavigation<OutLineControl>();
             containerRegistry.RegisterForNavigation<ViewModularContent>();
             containerRegistry.RegisterForNavigation<SplitScreenContent>();
             containerRegistry.RegisterForNavigation<ThemesContent>();

+ 370 - 0
PDF Office/CustomControl/PathButton.cs

@@ -0,0 +1,370 @@
+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.CustomControl
+{
+    public class PathButton : Button
+    {
+        static PathButton()
+        {
+            DefaultStyleKeyProperty.OverrideMetadata(typeof(PathButton), new FrameworkPropertyMetadata(typeof(PathButton)));
+        }
+
+        public override void OnApplyTemplate()
+        {
+            base.OnApplyTemplate();
+            if (this.MouseOverBackground == null)
+            {
+                this.MouseOverBackground = Background;
+            }
+            if (this.MouseDownBackground == null)
+            {
+                if (this.MouseOverBackground == null)
+                {
+                    this.MouseDownBackground = Background;
+                }
+                else
+                {
+                    this.MouseDownBackground = MouseOverBackground;
+                }
+            }
+            if (this.MouseOverBorderBrush == null)
+            {
+                this.MouseOverBorderBrush = BorderBrush;
+            }
+            if (this.MouseDownBorderBrush == null)
+            {
+                if (this.MouseOverBorderBrush == null)
+                {
+                    this.MouseDownBorderBrush = BorderBrush;
+                }
+                else
+                {
+                    this.MouseDownBorderBrush = MouseOverBorderBrush;
+                }
+            }
+            if (this.MouseOverForeground == null)
+            {
+                this.MouseOverForeground = Foreground;
+            }
+            if (this.MouseDownForeground == null)
+            {
+                if (this.MouseOverForeground == null)
+                {
+                    this.MouseDownForeground = Foreground;
+                }
+                else
+                {
+                    this.MouseDownForeground = this.MouseOverForeground;
+                }
+            }
+            if (this.IconChecked == null)
+            {
+                if (this.IconPress == null)
+                {
+                    this.IconChecked = Icon;
+                }
+                else
+                {
+                    this.IconChecked = this.IconPress;
+                }
+            }
+
+            if (this.IconCheckedFill == null)
+            {
+                if (this.IconPressFill == null)
+                {
+                    this.IconCheckedFill = IconFill;
+                }
+                else
+                {
+                    this.IconCheckedFill = this.IconPressFill;
+                }
+            }
+        }
+
+        #region 依赖项属性  
+
+        /// <summary>  
+        /// 鼠标移上去的背景颜色  
+        /// </summary>  
+        public static readonly DependencyProperty MouseOverBackgroundProperty
+            = DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(PathButton));
+
+        /// <summary>  
+        /// 鼠标按下去的背景颜色  
+        /// </summary>  
+        public static readonly DependencyProperty MouseDownBackgroundProperty
+            = DependencyProperty.Register("MouseDownBackground", typeof(Brush), typeof(PathButton));
+
+        /// <summary>  
+        /// 鼠标移上去的字体颜色  
+        /// </summary>  
+        public static readonly DependencyProperty MouseOverForegroundProperty
+            = DependencyProperty.Register("MouseOverForeground", typeof(Brush), typeof(PathButton), new PropertyMetadata(null, null));
+
+        /// <summary>  
+        /// 鼠标按下去的字体颜色  
+        /// </summary>  
+        public static readonly DependencyProperty MouseDownForegroundProperty
+            = DependencyProperty.Register("MouseDownForeground", typeof(Brush), typeof(PathButton), new PropertyMetadata(null, null));
+
+        /// <summary>  
+        /// 鼠标移上去的边框颜色  
+        /// </summary>  
+        public static readonly DependencyProperty MouseOverBorderBrushProperty
+            = DependencyProperty.Register("MouseOverBorderBrush", typeof(Brush), typeof(PathButton), new PropertyMetadata(null, null));
+
+        /// <summary>  
+        /// 鼠标按下去的边框颜色  
+        /// </summary>  
+        public static readonly DependencyProperty MouseDownBorderBrushProperty
+            = DependencyProperty.Register("MouseDownBorderBrush", typeof(Brush), typeof(PathButton), new PropertyMetadata(null, null));
+
+        /// <summary>  
+        /// 圆角  
+        /// </summary>  
+        public static readonly DependencyProperty CornerRadiusProperty
+            = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(PathButton), null);
+
+        //图标  
+        public static readonly DependencyProperty IconProperty
+            = DependencyProperty.Register("Icon", typeof(Geometry), typeof(PathButton), null);
+
+        //图标填充色  
+        public static readonly DependencyProperty IconFillProperty
+            = DependencyProperty.Register("IconFill", typeof(Brush), typeof(PathButton), null);
+
+        //图标透明度 
+        public static readonly DependencyProperty IconOpacityProperty
+            = DependencyProperty.Register("IconOpacity", typeof(double), typeof(PathButton), null);
+
+        //按钮是否被选中
+        public static readonly DependencyProperty IsCheckedProperty
+            = DependencyProperty.Register("IsChecked", typeof(bool), typeof(PathButton), null);
+
+        //选中的图标  
+        public static readonly DependencyProperty IconCheckedProperty
+            = DependencyProperty.Register("IconChecked", typeof(Geometry), typeof(PathButton), null);
+
+        //鼠标移上去的图标填充色   
+        public static readonly DependencyProperty IconCheckedFillProperty
+            = DependencyProperty.Register("IconCheckedFill", typeof(Brush), typeof(PathButton), null);
+
+        //鼠标移上去的透明度 
+        public static readonly DependencyProperty IconCheckedOpacityProperty
+            = DependencyProperty.Register("IconCheckedOpacity", typeof(double), typeof(PathButton), null);
+
+        //鼠标移上去的图标  
+        public static readonly DependencyProperty IconMouseOverProperty
+            = DependencyProperty.Register("IconMouseOver", typeof(Geometry), typeof(PathButton), null);
+
+        //鼠标移上去的图标填充色   
+        public static readonly DependencyProperty IconMouseOverFillProperty
+            = DependencyProperty.Register("IconMouseOverFill", typeof(Brush), typeof(PathButton), null);
+
+        //鼠标移上去的透明度 
+        public static readonly DependencyProperty IconMouseOverOpacityProperty
+            = DependencyProperty.Register("IconMouseOverOpacity", typeof(double), typeof(PathButton), null);
+
+        //鼠标按下去的图标
+        public static readonly DependencyProperty IconPressProperty
+            = DependencyProperty.Register("IconPress", typeof(Geometry), typeof(PathButton), null);
+
+        //鼠标按下去的图标填充色   
+        public static readonly DependencyProperty IconPressFillProperty
+            = DependencyProperty.Register("IconPressFill", typeof(Brush), typeof(PathButton), null);
+
+        //鼠标按下去的透明度 
+        public static readonly DependencyProperty IconPressOpacityProperty
+            = DependencyProperty.Register("IconPressOpacity", typeof(double), typeof(PathButton), null);
+
+        //图标高度  
+        public static readonly DependencyProperty IconHeightProperty
+            = DependencyProperty.Register("IconHeight", typeof(double), typeof(PathButton), new PropertyMetadata(24.0, null));
+
+        //图标宽度  
+        public static readonly DependencyProperty IconWidthProperty
+            = DependencyProperty.Register("IconWidth", typeof(double), typeof(PathButton), new PropertyMetadata(24.0, null));
+
+        //图标和内容的对齐方式  
+        public static readonly DependencyProperty IconContentOrientationProperty
+            = DependencyProperty.Register("IconContentOrientation", typeof(Orientation), typeof(PathButton), new PropertyMetadata(Orientation.Horizontal, null));
+
+        //图标和内容的距离  
+        public static readonly DependencyProperty IconContentMarginProperty
+            = DependencyProperty.Register("IconContentMargin", typeof(Thickness), typeof(PathButton), new PropertyMetadata(new Thickness(0, 0, 0, 0), null));
+
+        #endregion
+
+        #region 属性包装 
+
+        public Brush MouseOverBackground
+        {
+            get
+            {
+                return (Brush)GetValue(MouseOverBackgroundProperty);
+            }
+            set { SetValue(MouseOverBackgroundProperty, value); }
+        }
+
+        public Brush MouseDownBackground
+        {
+            get
+            {
+                return (Brush)GetValue(MouseDownBackgroundProperty);
+            }
+            set { SetValue(MouseDownBackgroundProperty, value); }
+        }
+
+        public Brush MouseOverForeground
+        {
+            get
+            {
+                return (Brush)GetValue(MouseOverForegroundProperty);
+            }
+            set { SetValue(MouseOverForegroundProperty, value); }
+        }
+
+        public Brush MouseDownForeground
+        {
+            get
+            {
+                return (Brush)GetValue(MouseDownForegroundProperty);
+            }
+            set { SetValue(MouseDownForegroundProperty, value); }
+        }
+
+        public Brush MouseOverBorderBrush
+        {
+            get { return (Brush)GetValue(MouseOverBorderBrushProperty); }
+            set { SetValue(MouseOverBorderBrushProperty, value); }
+        }
+
+        public Brush MouseDownBorderBrush
+        {
+            get { return (Brush)GetValue(MouseDownBorderBrushProperty); }
+            set { SetValue(MouseDownBorderBrushProperty, value); }
+        }
+
+        public CornerRadius CornerRadius
+        {
+            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
+            set { SetValue(CornerRadiusProperty, value); }
+        }
+
+        public Geometry Icon
+        {
+            get { return (Geometry)GetValue(IconProperty); }
+            set { SetValue(IconProperty, value); }
+        }
+
+        public Brush IconFill
+        {
+            get { return (Brush)GetValue(IconFillProperty); }
+            set { SetValue(IconFillProperty, value); }
+        }
+
+        public double IconOpacity
+        {
+            get { return (double)GetValue(IconOpacityProperty); }
+            set { SetValue(IconOpacityProperty, value); }
+        }
+        public bool IsChecked
+        {
+            get { return (bool)GetValue(IsCheckedProperty); }
+            set { SetValue(IsCheckedProperty, value); }
+        }
+
+        public Geometry IconChecked
+        {
+            get { return (Geometry)GetValue(IconCheckedProperty); }
+            set { SetValue(IconCheckedProperty, value); }
+        }
+
+        public Brush IconCheckedFill
+        {
+            get { return (Brush)GetValue(IconCheckedFillProperty); }
+            set { SetValue(IconCheckedFillProperty, value); }
+        }
+
+        public double IconCheckedOpacity
+        {
+            get { return (double)GetValue(IconCheckedOpacityProperty); }
+            set { SetValue(IconCheckedOpacityProperty, value); }
+        }
+        public Geometry IconMouseOver
+        {
+            get { return (Geometry)GetValue(IconMouseOverProperty); }
+            set { SetValue(IconMouseOverProperty, value); }
+        }
+
+        public Brush IconMouseOverFill
+        {
+            get { return (Brush)GetValue(IconMouseOverProperty); }
+            set { SetValue(IconMouseOverProperty, value); }
+        }
+
+        public double IconMouseOverOpacity
+        {
+            get { return (double)GetValue(IconMouseOverProperty); }
+            set { SetValue(IconMouseOverProperty, value); }
+        }
+
+        public Geometry IconPress
+        {
+            get { return (Geometry)GetValue(IconPressProperty); }
+            set { SetValue(IconPressProperty, value); }
+        }
+
+        public Brush IconPressFill
+        {
+            get { return (Brush)GetValue(IconPressFillProperty); }
+            set { SetValue(IconPressFillProperty, value); }
+        }
+
+        public double IconPressOpacity
+        {
+            get { return (double)GetValue(IconPressOpacityProperty); }
+            set { SetValue(IconPressOpacityProperty, value); }
+        }
+
+        public double IconHeight
+        {
+            get { return (double)GetValue(IconHeightProperty); }
+            set { SetValue(IconHeightProperty, value); }
+        }
+
+        public double IconWidth
+        {
+            get { return (double)GetValue(IconWidthProperty); }
+            set { SetValue(IconWidthProperty, value); }
+        }
+
+        public Orientation IconContentOrientation
+        {
+            get { return (Orientation)GetValue(IconContentOrientationProperty); }
+            set { SetValue(IconContentOrientationProperty, value); }
+        }
+
+        public Thickness IconContentMargin
+        {
+            get { return (Thickness)GetValue(IconContentMarginProperty); }
+            set { SetValue(IconContentMarginProperty, value); }
+        }
+
+        #endregion
+    }
+}

+ 84 - 0
PDF Office/Model/BOTA/OutlineNode.cs

@@ -0,0 +1,84 @@
+using ComPDFKit.PDFDocument;
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PDF_Office.Model.BOTA
+{
+    public class OutlineNode : BindableBase
+    {
+        /// <summary>
+        /// 父类大纲
+        /// </summary>
+        private OutlineNode parent = null;
+
+        public OutlineNode Parent
+        {
+            get { return parent; }
+            set
+            {
+                SetProperty(ref parent, value);
+            }
+        }
+        /// <summary>
+        /// 当前大纲对象
+        /// </summary>
+        private CPDFOutline outline = null;
+
+        public CPDFOutline Outline
+        {
+            get { return outline; }
+            set
+            {
+                SetProperty(ref outline, value);
+            }
+        }
+
+        /// <summary>
+        /// 子类大纲集合
+        /// </summary>
+        private ObservableCollection<OutlineNode> chlidlist = new ObservableCollection<OutlineNode>();
+
+        public ObservableCollection<OutlineNode> Chlidlist
+        {
+            get { return chlidlist; }
+            set
+            {
+                SetProperty(ref chlidlist, value);
+            }
+        }
+
+        /// <summary>
+        /// 控制虚线的显示
+        /// </summary>
+        private bool isInsertNextLayer = false;
+
+        public bool IsInsertNextLayer
+        {
+            get { return isInsertNextLayer; }
+            set
+            {
+                SetProperty(ref isInsertNextLayer, value);
+            }
+        }
+
+        /// <summary>
+        /// 控制实线的显示
+        /// </summary>
+        private bool isInsertCurrentLayer = false;
+
+        public bool IsInsertCurrentLayer
+        {
+            get { return isInsertCurrentLayer; }
+            set
+            {
+                SetProperty(ref isInsertCurrentLayer, value);
+            }
+        }
+
+    }
+}

+ 18 - 0
PDF Office/PDF Office.csproj

@@ -209,6 +209,7 @@
     <Compile Include="CustomControl\PageTurningPreview.xaml.cs">
       <DependentUpon>PageTurningPreview.xaml</DependentUpon>
     </Compile>
+    <Compile Include="CustomControl\PathButton.cs" />
     <Compile Include="CustomControl\SystemControl\CustomCommandAction .cs" />
     <Compile Include="CustomControl\SystemControl\RoutedEventTrigger.cs" />
     <Compile Include="CustomControl\ToastControl.xaml.cs">
@@ -237,6 +238,7 @@
     <Compile Include="Helper\SetterAction.cs" />
     <Compile Include="Helper\SettingHelper.cs" />
     <Compile Include="Helper\ToolMethod.cs" />
+    <Compile Include="Model\BOTA\OutlineNode.cs" />
     <Compile Include="Model\CloudDrive\CloudDriveItem.cs" />
     <Compile Include="Model\CloudDrive\CloudFiles.cs" />
     <Compile Include="Model\DialogNames.cs" />
@@ -294,6 +296,7 @@
       <AutoGen>True</AutoGen>
     </Compile>
     <Compile Include="ViewModels\BOTA\BookmarkContentViewModel.cs" />
+    <Compile Include="ViewModels\BOTA\OutLineControlViewModel.cs" />
     <Compile Include="ViewModels\Dialog\BOTA\AddBookmarkDialogViewModel.cs" />
     <Compile Include="ViewModels\Dialog\BOTA\BookmarkInfoDialogViewModel.cs" />
     <Compile Include="ViewModels\EditTools\Background\BackgroundContentViewModel.cs" />
@@ -392,6 +395,9 @@
     <Compile Include="Views\BOTA\BOTAContent.xaml.cs">
       <DependentUpon>BOTAContent.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Views\BOTA\OutLineControl.xaml.cs">
+      <DependentUpon>OutLineControl.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Views\BottomToolContent.xaml.cs">
       <DependentUpon>BottomToolContent.xaml</DependentUpon>
     </Compile>
@@ -745,6 +751,14 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Styles\OutLineItemStyle.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Styles\PathButtonStyle.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Styles\RadioButtonStyle.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
@@ -785,6 +799,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Views\BOTA\OutLineControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Views\BottomToolContent.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 158 - 0
PDF Office/Styles/OutLineItemStyle.xaml


+ 128 - 0
PDF Office/Styles/PathButtonStyle.xaml

@@ -0,0 +1,128 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+                    xmlns:customControl="clr-namespace:PDF_Office.CustomControl"
+                    >
+    <Style TargetType="{x:Type customControl:PathButton}">
+        <Setter Property="IconOpacity" Value="1" />
+        <Setter Property="IconMouseOverOpacity" Value="1" />
+        <Setter Property="IconPressOpacity" Value="1" />
+        <Setter Property="IconCheckedOpacity" Value="1" />
+        <Setter Property="IsChecked" Value="false" />
+        <Setter Property="Background" Value="Transparent" />
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="{x:Type customControl:PathButton}">
+
+                    <Border
+                        Background="{TemplateBinding Background}"
+                        BorderBrush="{TemplateBinding BorderBrush}"
+                        BorderThickness="{TemplateBinding BorderThickness}">
+                        <Grid x:Name="grid" Background="{TemplateBinding Background}">
+                            <Border
+                                x:Name="PART_Border"
+                                Background="{TemplateBinding Background}"
+                                BorderBrush="{TemplateBinding BorderBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="{TemplateBinding CornerRadius}" />
+
+                            <Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}">
+                                <StackPanel
+                                    Margin="{TemplateBinding Padding}"
+                                    HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"
+                                    Orientation="{TemplateBinding IconContentOrientation}">
+                                    <Grid HorizontalAlignment="Center" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
+                                        <Path
+                                            x:Name="PART_Icon"
+                                            Width="{TemplateBinding IconWidth}"
+                                            Height="{TemplateBinding IconHeight}"
+                                            Data="{TemplateBinding Icon}"
+                                            Fill="{TemplateBinding IconFill}"
+                                            Opacity="{TemplateBinding IconOpacity}" />
+                                        <Path
+                                            x:Name="PART_MouseOverIcon"
+                                            Width="{TemplateBinding IconWidth}"
+                                            Height="{TemplateBinding IconHeight}"
+                                            Data="{TemplateBinding IconMouseOver}"
+                                            Fill="{TemplateBinding IconMouseOverFill}"
+                                            Opacity="{TemplateBinding IconMouseOverOpacity}"
+                                            Visibility="Collapsed" />
+                                        <Path
+                                            x:Name="PART_PressIcon"
+                                            Width="{TemplateBinding IconWidth}"
+                                            Height="{TemplateBinding IconHeight}"
+                                            Data="{TemplateBinding IconPress}"
+                                            Fill="{TemplateBinding IconPressFill}"
+                                            Opacity="{TemplateBinding IconPressOpacity}"
+                                            Visibility="Collapsed" />
+                                        <Path
+                                            x:Name="PART_CheckedIcon"
+                                            Width="{TemplateBinding IconWidth}"
+                                            Height="{TemplateBinding IconHeight}"
+                                            Data="{TemplateBinding IconChecked}"
+                                            Fill="{TemplateBinding IconCheckedFill}"
+                                            Opacity="{TemplateBinding IconCheckedOpacity}"
+                                            Visibility="Collapsed" />
+                                    </Grid>
+                                    <TextBlock
+                                        x:Name="PART_Content"
+                                        Margin="{TemplateBinding IconContentMargin}"
+                                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+                                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+                                        Foreground="{TemplateBinding Foreground}"
+                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
+                                        Text="{TemplateBinding Content}"
+                                        TextTrimming="CharacterEllipsis" />
+                                </StackPanel>
+                            </Grid>
+                        </Grid>
+                    </Border>
+
+                    <ControlTemplate.Triggers>
+                        <Trigger Property="IsMouseOver" Value="True">
+                            <Setter TargetName="PART_Content" Property="Foreground" Value="{Binding MouseOverForeground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_Border" Property="Background" Value="{Binding MouseOverBackground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_Border" Property="BorderBrush" Value="{Binding MouseOverBorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_MouseOverIcon" Property="Visibility" Value="Visible" />
+                            <Setter TargetName="PART_Icon" Property="Visibility" Value="Collapsed" />
+                            <Setter TargetName="PART_PressIcon" Property="Visibility" Value="Collapsed" />
+                            <Setter TargetName="PART_CheckedIcon" Property="Visibility" Value="Collapsed" />
+                        </Trigger>
+
+                        <Trigger Property="IsPressed" Value="True">
+                            <Setter TargetName="PART_Content" Property="Foreground" Value="{Binding MouseDownForeground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_Border" Property="Background" Value="{Binding MouseDownBackground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_Border" Property="BorderBrush" Value="{Binding MouseDownBorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_PressIcon" Property="Visibility" Value="Visible" />
+                            <Setter TargetName="PART_Icon" Property="Visibility" Value="Collapsed" />
+                            <Setter TargetName="PART_MouseOverIcon" Property="Visibility" Value="Collapsed" />
+                            <Setter TargetName="PART_CheckedIcon" Property="Visibility" Value="Collapsed" />
+                        </Trigger>
+
+                        <Trigger Property="IsEnabled" Value="False">
+                            <Setter Property="Opacity" Value="0.5" />
+                        </Trigger>
+
+                        <Trigger Property="IsChecked" Value="True">
+                            <Setter TargetName="PART_Content" Property="Foreground" Value="{Binding MouseOverForeground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_Border" Property="Background" Value="{Binding MouseOverBackground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_Border" Property="BorderBrush" Value="{Binding MouseOverBorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type customControl:PathButton}}}" />
+                            <Setter TargetName="PART_MouseOverIcon" Property="Visibility" Value="Collapsed" />
+                            <Setter TargetName="PART_Icon" Property="Visibility" Value="Collapsed" />
+                            <Setter TargetName="PART_PressIcon" Property="Visibility" Value="Collapsed" />
+                            <Setter TargetName="PART_CheckedIcon" Property="Visibility" Value="Visible" />
+                        </Trigger>
+
+                        <Trigger SourceName="PART_Content" Property="Text" Value="">
+                            <Setter TargetName="PART_Content" Property="Visibility" Value="Collapsed" />
+                        </Trigger>
+
+                        <Trigger SourceName="PART_Content" Property="Text" Value="{x:Null}">
+                            <Setter TargetName="PART_Content" Property="Visibility" Value="Collapsed" />
+                        </Trigger>
+                    </ControlTemplate.Triggers>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+</ResourceDictionary>

+ 1 - 1
PDF Office/ViewModels/BOTA/BOTAContentViewModel.cs

@@ -65,7 +65,7 @@ namespace PDF_Office.ViewModels.BOTA
         {
             //绑定tabitem名字和对应的View控件名称
             viewNameByTabItem.Add("TabItemThumbnail", "PageEditContent");
-            viewNameByTabItem.Add("TabItemOutLine", "");
+            viewNameByTabItem.Add("TabItemOutLine", "OutLineControl");
             viewNameByTabItem.Add("TabItemBookMark", "BookmarkContent");
             viewNameByTabItem.Add("TabItemAnnotation", "");
             viewNameByTabItem.Add("TabItemSearch", "");

+ 89 - 0
PDF Office/ViewModels/BOTA/OutLineControlViewModel.cs

@@ -0,0 +1,89 @@
+using ComPDFKit.PDFDocument;
+using ComPDFKitViewer.PdfViewer;
+using PDF_Office.Model;
+using PDF_Office.Model.BOTA;
+using Prism.Mvvm;
+using Prism.Regions;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PDF_Office.ViewModels.BOTA
+{
+    class OutLineControlViewModel : BindableBase, INavigationAware
+    {
+        private CPDFViewer PDFViewer;
+        public ObservableCollection<OutlineNode> Outlinelist { get; set; }
+
+        private bool isInsertHead = false;
+
+        public bool IsInsertHead
+        {
+            get { return isInsertHead; }
+            set
+            {
+                SetProperty(ref isInsertHead, value);
+            }
+        }
+
+        public OutLineControlViewModel()
+        {
+            Outlinelist = new ObservableCollection<OutlineNode>();
+        }
+        public bool IsNavigationTarget(NavigationContext navigationContext)
+        {
+            return true;
+        }
+
+        public void OnNavigatedFrom(NavigationContext navigationContext)
+        {
+            return;
+        }
+
+        public void OnNavigatedTo(NavigationContext navigationContext)
+        {
+            navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
+            if (PDFViewer == null)
+            {
+                return;
+            }
+            List<CPDFOutline> datasource = PDFViewer.Document.GetOutlineList();
+            Outlinelist.Clear();
+            foreach (CPDFOutline item in datasource)
+            {
+                OutlineNode dto = ConvertCPDFToOutlineNode(item, null);
+                if (dto != null)
+                {
+                    Outlinelist.Add(dto);
+                }
+            }
+        }
+
+        private OutlineNode ConvertCPDFToOutlineNode(CPDFOutline outline, OutlineNode parent)
+        {
+            OutlineNode node = new OutlineNode();
+            if (outline != null)
+            {
+                node.IsInsertNextLayer = false;
+                node.IsInsertCurrentLayer = false;
+                node.Outline = outline;
+                if (parent != null)
+                {
+                    node.Parent = parent;
+                }
+                node.Chlidlist = new ObservableCollection<OutlineNode>();
+                if (outline.ChildList.Count > 0)
+                {
+                    foreach (CPDFOutline item in outline.ChildList)
+                    {
+                        node.Chlidlist.Add(ConvertCPDFToOutlineNode(item, node));
+                    }
+                }
+            }
+            return node;
+        }
+    }
+}

+ 119 - 0
PDF Office/Views/BOTA/OutLineControl.xaml

@@ -0,0 +1,119 @@
+<UserControl x:Class="PDF_Office.Views.BOTA.OutLineControl"
+             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:PDF_Office.Views.BOTA"
+             xmlns:customcontrol="clr-namespace:PDF_Office.CustomControl"
+             xmlns:model="clr-namespace:PDF_Office.Model.BOTA"
+             xmlns:bota="clr-namespace:PDF_Office.ViewModels.BOTA" d:DataContext="{d:DesignInstance Type=bota:OutLineControlViewModel}"
+             mc:Ignorable="d" >
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <ResourceDictionary Source="pack://application:,,,/PDF Office;component/Styles/OutLineItemStyle.xaml"/>
+            </ResourceDictionary.MergedDictionaries>
+
+        </ResourceDictionary>
+    </UserControl.Resources>
+    <Grid  Background="Transparent">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="40"/>
+            <RowDefinition/>
+        </Grid.RowDefinitions>
+        <Grid x:Name="Header">
+            <TextBlock x:Name="TxtTitle" Margin="12,0,0,0" HorizontalAlignment="Left"
+                    VerticalAlignment="Center" FontSize="18" FontWeight="SemiBold" Text="Outline" />
+            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
+                <customcontrol:PathButton
+            Height="24" Width="24"  IconHeight="20"  IconWidth="20" 
+            Icon="{StaticResource Ic_AddButtonPath}"  IconFill="Red"
+            IconPress="{StaticResource Ic_AddButtonPath}" IconPressFill="#C04CF8"
+            IconMouseOver="{StaticResource Ic_AddButtonPath}" IconMouseOverFill="#C04CF8" />
+                <customcontrol:PathButton
+                    x:Name="BtnMore"
+                    Click="BtnMore_Click"
+            Height="24" Width="24"  IconHeight="20"  IconWidth="20" 
+            Icon="{StaticResource Ic_MoreButtonPath}"  IconFill="Red"
+            IconPress="{StaticResource Ic_MoreButtonPath}" IconPressFill="#C04CF8"
+            IconMouseOver="{StaticResource Ic_MoreButtonPath}" IconMouseOverFill="#C04CF8" >
+                    <customcontrol:PathButton.ContextMenu>
+                        <ContextMenu
+                            Name="MenuMore">
+                            <ContextMenu.ItemContainerStyle>
+                                <Style TargetType="MenuItem">
+                                    <Setter Property="Padding" Value="-25,7,-40,7" />
+                                    <Setter Property="VerticalContentAlignment" Value="Center" />
+                                </Style>
+                            </ContextMenu.ItemContainerStyle>
+                            <MenuItem
+                                Name="MenuDeleteAll"
+                                Header="Delete All Outline" />
+                            <MenuItem
+                                Name="MenuExpandAll"
+                                Header="一键展开" />
+                            <MenuItem
+                                Name="MenuCollapseAll"
+                                Header="一键折叠" />
+                        </ContextMenu>
+                    </customcontrol:PathButton.ContextMenu>
+                </customcontrol:PathButton>
+            </StackPanel>
+        </Grid>
+
+        <StackPanel Margin="10,0" x:Name="FirstOulineLine" Orientation="Horizontal"  VerticalAlignment="Bottom" Visibility="{Binding IsInsertHead,Converter={StaticResource BoolToVisible}}">
+            <Ellipse Width="8" Height="8" Fill="White" Stroke="#FF0078D7" StrokeThickness="1.5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"/>
+            <Rectangle Margin="-1,0,0,2" Width="{Binding ElementName=Header,Path=ActualWidth}" HorizontalAlignment="Stretch" Height="1.5" StrokeDashArray="2" VerticalAlignment="Bottom" Fill="#FF0078D7"/>
+        </StackPanel>
+        <Grid Grid.Row="1"
+               DragOver="Grid_DragOver">
+            <TreeView x:Name="OutlineView" Grid.Row="1" ItemsSource="{Binding Outlinelist}"
+                BorderThickness="0" AllowDrop="True"
+                VirtualizingPanel.ScrollUnit="Pixel"
+                PreviewMouseMove="OutlineView_PreviewMouseMove"      
+                ScrollViewer.HorizontalScrollBarVisibility="Disabled">
+                <TreeView.ItemTemplate>
+                    <HierarchicalDataTemplate DataType="{x:Type model:OutlineNode}" ItemsSource="{Binding Path=Chlidlist}">
+                        <Grid>
+                            <Grid.ColumnDefinitions>
+                                <ColumnDefinition />
+                                <ColumnDefinition Width="auto" />
+                            </Grid.ColumnDefinitions>
+                            <Grid.ContextMenu>
+                                <ContextMenu>
+                                    <MenuItem Header="1"/>
+                                    <MenuItem Header="2"/>
+                                    <MenuItem Header="3"/>
+                                    <MenuItem Header="4"/>
+
+                                    <MenuItem Header="5"/>
+                                    <MenuItem Header="6"/>
+                                    <MenuItem Header="7"/>
+
+                                    <MenuItem Header="8"/>
+                                    <MenuItem Header="9"/>
+                                </ContextMenu>
+                            </Grid.ContextMenu>
+                            <DockPanel x:Name="ContentPanel">
+                                <TextBlock x:Name="Content" Text="{Binding Outline.Title}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"/>
+                                <TextBlock x:Name="PageIndex" Grid.Column="1" HorizontalAlignment="Right"  VerticalAlignment="Center" Text="1"/>
+                            </DockPanel>
+
+                            <StackPanel  Orientation="Horizontal" HorizontalAlignment="Stretch" Visibility="{Binding IsInsertNextLayer, Converter={StaticResource BoolToVisible}}" >
+                                <Ellipse Margin="0,0,0,0" Width="8" Height="8" Fill="White" Stroke="#FF0078D7"  StrokeThickness="1.5" VerticalAlignment="Bottom"/>
+                                <Line Margin="-1,0,0,2" X1="0"  X2="{Binding ElementName=ContentPanel,Path=ActualWidth}" HorizontalAlignment="Stretch" StrokeThickness="1.5" StrokeDashArray="2" Stroke="#FF0078D7" VerticalAlignment="Bottom"/>
+                            </StackPanel>
+                            <Grid x:Name="RenameGrid" Visibility="{Binding ElementName=Content,Path=Visibility,Mode=TwoWay,Converter={StaticResource UnVisivleConvert}}">
+                                <TextBox x:Name="ReName" HorizontalAlignment="Left" VerticalAlignment="Center"/>
+                            </Grid>
+                        </Grid>
+                    </HierarchicalDataTemplate>
+                </TreeView.ItemTemplate>
+                <TreeView.ItemContainerStyle>
+                    <Style BasedOn="{StaticResource OutLineItemStyle}" TargetType="TreeViewItem">
+                    </Style>
+                </TreeView.ItemContainerStyle>
+            </TreeView>
+        </Grid>
+    </Grid>
+</UserControl>

+ 103 - 0
PDF Office/Views/BOTA/OutLineControl.xaml.cs

@@ -0,0 +1,103 @@
+using ComPDFKit.PDFDocument;
+using PDF_Office.Helper;
+using PDF_Office.Model.BOTA;
+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.BOTA
+{
+    /// <summary>
+    /// OutLineControl.xaml 的交互逻辑
+    /// </summary>
+    public partial class OutLineControl : UserControl
+    {
+        public OutLineControl()
+        {
+            InitializeComponent();
+        }
+
+        private void BtnMore_Click(object sender, RoutedEventArgs e)
+        {
+            MenuMore.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
+            MenuMore.PlacementTarget = BtnMore;
+            MenuMore.IsOpen = true;
+        }
+        private void OutlineView_PreviewMouseMove(object sender, MouseEventArgs e)
+        {
+            if (e.LeftButton == MouseButtonState.Pressed )
+            {
+                var pos = e.GetPosition(OutlineView);
+                HitTestResult result = VisualTreeHelper.HitTest(OutlineView, pos);
+                if (result == null)
+                {
+                    return;
+                }
+                var treeViewItem = CommonHelper.FindVisualParent<TreeViewItem>(result.VisualHit);
+                if (treeViewItem == null)
+                {
+                    return;
+                }
+                DataObject dataObj = new DataObject(treeViewItem);
+                DragDrop.DoDragDrop(OutlineView, dataObj, DragDropEffects.Move);
+                return;
+            }
+        }
+
+        private TreeViewItem Treeviewitem = null;
+        private void Grid_DragOver(object sender, DragEventArgs e)
+        {
+            TreeViewItem sourceitem = e.Data.GetData(typeof(TreeViewItem)) as TreeViewItem;
+            if (sourceitem == null)
+            {
+                return;
+            }
+            Point pos = e.GetPosition(OutlineView);
+            HitTestResult result = VisualTreeHelper.HitTest(OutlineView, pos);
+            if (result != null)
+            {
+                TreeViewItem treeviewitem = CommonHelper.FindVisualParent<TreeViewItem>(result.VisualHit);
+                if (treeviewitem != null)
+                {
+                    Point p = treeviewitem.TranslatePoint(new Point(0, 0), OutlineView);
+                    if (Treeviewitem==null)
+                    {
+                        Treeviewitem = treeviewitem;
+                    }
+                    else if (!Treeviewitem.Equals(treeviewitem))
+                    {
+                        (Treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = false;
+                        (Treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = false;
+                        Treeviewitem = treeviewitem;
+                    }
+                    else
+                    {
+                        (Treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = false;
+                        (Treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = false;
+                    }
+                    if (pos.Y < p.Y + 16)
+                    {
+                        (treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = true;
+                    }
+                    else
+                    {
+                        (treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = true;
+                    }
+                }
+
+            }
+
+        }
+    }
+}