走进WPF之开发类似Visio软件


当你想画一个流程图的时候,你会发现,很多软件要么需要秘钥,要么需要会员,这时我就在想,可不可自己制作一款流程图软件呢?本文以一个简单的小例子,简述如何利用WPF制作属于自己的流程图软件,仅供学习分享使用,如有不足之处,还请指正。

涉及知识点

本示例主要通过WPF技术进行开发,涉及知识点如下:

  1. WPF绘图,如矩形,直线等功能的相关图形技术。
  2. Thumb控件,本控件可以由用户自由拖动,示例中所用到的可移动的图形控件,都继承于Thumb控件。

Thumb控件简介

Thumb控件是WPF提供的用于用户拖动的控件。默认情况下,Thumb控件并不在工具箱中,需要手动添加,如下所示:

工具箱-->常规-->右键-->选择项,然后打开【选择工具箱对话框】,如下所示:

在选【择工具箱项】页面,打开WPF组件-->选择Thumb-->点击确定按钮,如下所示:

 添加成功后,即可从工具箱拖动到页面,如下所示:

关于Thumb控件的简介,如下所示:

  1 namespace System.Windows.Controls.Primitives
  2 {
  3     //
  4     // 摘要:
  5     //     表示可以由用户拖动的控件。
  6     [DefaultEvent("DragDelta")]
  7     [Localizability(LocalizationCategory.NeverLocalize)]
  8     public class Thumb : Control
  9     {
 10         //
 11         // 摘要:
 12         //     标识 System.Windows.Controls.Primitives.Thumb.DragStarted 路由事件。
 13         //
 14         // 返回结果:
 15         //     System.Windows.Controls.Primitives.Thumb.DragStarted 路由事件的标识符。
 16         public static readonly RoutedEvent DragStartedEvent;
 17         //
 18         // 摘要:
 19         //     标识 System.Windows.Controls.Primitives.Thumb.DragDelta 路由事件。
 20         //
 21         // 返回结果:
 22         //     System.Windows.Controls.Primitives.Thumb.DragDelta 路由事件的标识符。
 23         public static readonly RoutedEvent DragDeltaEvent;
 24         //
 25         // 摘要:
 26         //     标识 System.Windows.Controls.Primitives.Thumb.DragCompleted 路由事件。
 27         //
 28         // 返回结果:
 29         //     System.Windows.Controls.Primitives.Thumb.DragCompleted 路由事件的标识符。
 30         public static readonly RoutedEvent DragCompletedEvent;
 31         //
 32         // 摘要:
 33         //     标识 System.Windows.Controls.Primitives.Thumb.IsDragging 依赖属性。
 34         //
 35         // 返回结果:
 36         //     System.Windows.Controls.Primitives.Thumb.IsDragging 依赖项属性的标识符。
 37         public static readonly DependencyProperty IsDraggingProperty;
 38 
 39         //
 40         // 摘要:
 41         //     初始化 System.Windows.Controls.Primitives.Thumb 类的新实例。
 42         public Thumb();
 43 
 44         //
 45         // 摘要:
 46         //     获取是否 System.Windows.Controls.Primitives.Thumb 控件具有逻辑焦点和捕获鼠标并按下鼠标左键。
 47         //
 48         // 返回结果:
 49         //     true 如果 System.Windows.Controls.Primitives.Thumb 控件具有焦点且鼠标捕获; 否则为 false。 默认值为
 50         //     false。
 51         [Bindable(true)]
 52         [Browsable(false)]
 53         [Category("Appearance")]
 54         public bool IsDragging { get; protected set; }
 55 
 56         //
 57         // 摘要:
 58         //     发生时 System.Windows.Controls.Primitives.Thumb 控件接收逻辑焦点和鼠标捕获。
 59         [Category("Behavior")]
 60         public event DragStartedEventHandler DragStarted;
 61         //
 62         // 摘要:
 63         //     根据鼠标位置更改时出现了一个或多个次 System.Windows.Controls.Primitives.Thumb 控件具有逻辑焦点和鼠标捕获。
 64         [Category("Behavior")]
 65         public event DragDeltaEventHandler DragDelta;
 66         //
 67         // 摘要:
 68         //     发生时 System.Windows.Controls.Primitives.Thumb 控件失去鼠标捕获。
 69         [Category("Behavior")]
 70         public event DragCompletedEventHandler DragCompleted;
 71 
 72         //
 73         // 摘要:
 74         //     取消的拖动操作 System.Windows.Controls.Primitives.Thumb。
 75         public void CancelDrag();
 76         //
 77         // 摘要:
 78         //     创建 System.Windows.Automation.Peers.AutomationPeer 为 System.Windows.Controls.Primitives.Thumb
 79         //     控件。
 80         //
 81         // 返回结果:
 82         //     一个 System.Windows.Automation.Peers.ThumbAutomationPeer 为 System.Windows.Controls.Primitives.Thumb
 83         //     控件。
 84         protected override AutomationPeer OnCreateAutomationPeer();
 85         //
 86         // 摘要:
 87         //     响应 System.Windows.Controls.Primitives.Thumb.IsDragging 属性值的更改。
 88         //
 89         // 参数:
 90         //   e:
 91         //     事件数据。
 92         protected virtual void OnDraggingChanged(DependencyPropertyChangedEventArgs e);
 93         //
 94         // 摘要:
 95         //     提供类处理 System.Windows.ContentElement.MouseLeftButtonDown 事件。
 96         //
 97         // 参数:
 98         //   e:
 99         //     事件数据。
100         protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e);
101         //
102         // 摘要:
103         //     提供类处理 System.Windows.ContentElement.MouseLeftButtonUp 事件。
104         //
105         // 参数:
106         //   e:
107         //     事件数据。
108         protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e);
109         //
110         // 摘要:
111         //     提供类处理 System.Windows.UIElement.MouseMove 事件。
112         //
113         // 参数:
114         //   e:
115         //     事件数据。
116         protected override void OnMouseMove(MouseEventArgs e);
117     }
118 }

通过上述摘要简介,发现Thumb控件提供了三个事件,分别是:

  • 拖动开始事件:public event DragStartedEventHandler DragStarted;
  • 拖动进行事件:public event DragDeltaEventHandler DragDelta;
  • 拖动完成事件:public event DragCompletedEventHandler DragCompleted;

 Thumb控件示例

首先在窗口页面上添加一个Thumb控件,然后分别添加三个事件,如下所示:

 1 <Window x:Class="DemoVisio.MainWindow1"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:DemoVisio"
 7         mc:Ignorable="d"
 8         Title="Thumb示例" Height="450" Width="800">
 9     <Canvas>
10         <Thumb x:Name="thumb" Canvas.Left="0" Canvas.Top="0"  Height="100"  Width="100"   DragStarted="thumb_DragStarted" DragDelta="thumb_DragDelta" DragCompleted="thumb_DragCompleted"/>
11 
12     Canvas>
13 Window>

然后在三个事件中添加代码,终点是DragDelta事件,如下所示:

 1 namespace DemoVisio
 2 {
 3     /// 
 4     /// MainWindow1.xaml 的交互逻辑
 5     /// 
 6     public partial class MainWindow1 : Window
 7     {
 8         public MainWindow1()
 9         {
10             InitializeComponent();
11         }
12 
13         private void thumb_DragStarted(object sender, DragStartedEventArgs e)
14         {
15             //开始拖动
16         }
17 
18         /// 
19         /// 拖动
20         /// 
21         /// 
22         /// 
23         private void thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
24         {
25             Thumb myThumb = (Thumb)sender;
26             double nTop = Canvas.GetTop(myThumb) + e.VerticalChange;
27             double nLeft = Canvas.GetLeft(myThumb) + e.HorizontalChange;
28             Canvas.SetTop(myThumb, nTop);
29             Canvas.SetLeft(myThumb, nLeft);
30         }
31 
32         private void thumb_DragCompleted(object sender, DragCompletedEventArgs e)
33         {
34             //拖动完成
35         }
36     }
37 }

注意,在XAML中,Thumb一定是在Canvas布局容器中,且一定要设置【Canvas.Left="0" Canvas.Top="0"】两个属性,如果不设置,在值为NaN,无法进行拖动。

默认情况下,Thumb控件就是一个丑丑的方块,如下所示:

拖动控件基类

在本示例中,流程图需要多种控件(如:圆形,矩形,线等),不能每一个控件都去实现那三个事件【DragStarted,DragDelta,DragCompleted】,所以需要定义一个基类ThumbControl,统一实现方案。具体如下所示:

 1 namespace DemoVisio
 2 {
 3     public class ThumbControl : Thumb
 4     {
 5         /// 
 6         /// 是否可以输入
 7         /// 
 8         public bool IsEnableInput { get { return (bool)GetValue(IsEnableInputProperty); } set {SetValue( IsEnableInputProperty, value); } }
 9 
10         /// 
11         /// 依赖属性
12         /// 
13         public static readonly DependencyProperty IsEnableInputProperty = DependencyProperty.Register("IsEnableInput",typeof(bool),typeof(ThumbControl));
14 
15         public ThumbControl():base() {
16             this.DragStarted += ThumbControl_DragStarted;
17             this.DragDelta += ThumbControl_DragDelta;
18             this.DragCompleted += ThumbControl_DragCompleted;
19             this.MouseDoubleClick += ThumbControl_MouseDoubleClick;
20             this.IsKeyboardFocusedChanged += ThumbControl_IsKeyboardFocusedChanged;
21         }
22 
23         public void SetIsEnableInput(bool flag)
24         {
25             this.IsEnableInput = flag;
26         }
27 
28         /// 
29         /// 是否具有键盘焦点
30         /// 
31         /// 
32         /// 
33         private void ThumbControl_IsKeyboardFocusedChanged(object sender, DependencyPropertyChangedEventArgs e)
34         {
35            
36             this.IsEnableInput = this.IsKeyboardFocused;
37            
38         }
39 
40         /// 
41         /// 双击事件
42         /// 
43         /// 
44         /// 
45         private void ThumbControl_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
46         {
47             this.IsEnableInput = true;
48         }
49 
50         private void ThumbControl_DragStarted(object sender, DragStartedEventArgs e)
51         {
52             //开始移动
53         }
54 
55         private void ThumbControl_DragDelta(object sender, DragDeltaEventArgs e)
56         {
57             Thumb myThumb = (Thumb)sender;
58             double nTop = Canvas.GetTop(myThumb) + e.VerticalChange;
59             double nLeft = Canvas.GetLeft(myThumb) + e.HorizontalChange;
60             Canvas.SetTop(myThumb, nTop);
61             Canvas.SetLeft(myThumb, nLeft);
62         }
63         
64         private void ThumbControl_DragCompleted(object sender, DragCompletedEventArgs e)
65         {
66             //移动结束
67         }
68     }
69 }

具体图形控件

封装了基类以后,其他控件可以在此基础上进行使用,通过ControlTemplate展现不同的形态,如下所示:

1. 矩形方块

在流程图中,矩形方块一般表示过程,实现代码如下所示:

 1 <UserControl x:Class="DemoVisio.SquareControl"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:local="clr-namespace:DemoVisio"
 7              mc:Ignorable="d" 
 8              d:DesignHeight="450" d:DesignWidth="800">
 9     <Canvas>
10         <local:ThumbControl x:Name="s" BorderThickness="1" Canvas.Top ="0" Canvas.Left="0" Width="100" Height="60" Background="AliceBlue">
11             <Thumb.Template>
12                 <ControlTemplate>
13                     <Border Width="{Binding ElementName=s, Path=Width}" Height="{Binding ElementName=s, Path=Height}" BorderBrush="Black" Background="{Binding ElementName=s, Path=Background}" BorderThickness="{Binding ElementName=s, Path=BorderThickness}" Padding="2">
14                         <TextBox Background="{Binding ElementName=s, Path=Background}" BorderThickness="0" VerticalAlignment="Center"  IsEnabled="{Binding ElementName=s, Path=IsEnableInput}" MinLines="3" MaxLines="3" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">TextBox>
15                     Border>
16 
17                 ControlTemplate>
18             Thumb.Template>
19         local:ThumbControl>
20     Canvas>
21 UserControl>

2. 圆形图

在流程图中,圆形一般表示开始和结束,如下所示:

 1 <UserControl x:Class="DemoVisio.CircleControl"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:local="clr-namespace:DemoVisio"
 7              mc:Ignorable="d" 
 8              d:DesignHeight="450" d:DesignWidth="800">
 9     <Canvas>
10         <local:ThumbControl x:Name="s" Canvas.Top ="0" Canvas.Left="0" Width="60" Height="60" Background="AliceBlue" BorderThickness="1" >
11             <local:ThumbControl.Template>
12                 <ControlTemplate>
13                     <Grid>
14                         <Border Width="{Binding Width}" Height="{Binding Height}" CornerRadius="30" BorderThickness="{Binding ElementName=s, Path=BorderThickness}" BorderBrush="Black" Background="{Binding ElementName=s, Path=Background}">
15                             <TextBox VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" MaxLines="2" MinLines="1" Width="{Binding Width}" Height="{Binding Height}" Background="{Binding ElementName=s, Path=Background}" BorderThickness="0" IsEnabled="{Binding ElementName=s, Path=IsEnableInput}">TextBox>
16                         Border>
17                     Grid>
18                 ControlTemplate>
19             local:ThumbControl.Template>
20 
21         local:ThumbControl>
22     Canvas>
23 UserControl>

3. 菱形图

在流程图中,菱形一般表示选择,表达程序中的布尔值。如下所示:

 1 <UserControl x:Class="DemoVisio.RhombusControl"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:local="clr-namespace:DemoVisio"
 7              mc:Ignorable="d" 
 8              d:DesignHeight="450" d:DesignWidth="800">
 9     <Canvas>
10         <local:ThumbControl x:Name="s" Canvas.Left="0" Canvas.Top="0"  Width="80" Height="80" Background="AliceBlue" BorderThickness="1"  >
11             <Thumb.Template>
12                 <ControlTemplate>
13                     <Border Width="{Binding ElementName=s, Path=Width}" Height="{Binding ElementName=s, Path=Height}" BorderBrush="Black" Background="{Binding ElementName=s, Path=Background}" BorderThickness="{Binding ElementName=s, Path=BorderThickness}" Padding="1">
14                         <TextBox Background="{Binding ElementName=s, Path=Background}" BorderThickness="0" VerticalAlignment="Center"  IsEnabled="{Binding ElementName=s, Path=IsEnableInput}" Width="50" Height="50" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
15                             <TextBox.RenderTransform>
16                                 <RotateTransform CenterX="25" CenterY="25" Angle="-45" >RotateTransform>
17                             TextBox.RenderTransform>
18                         TextBox>
19                     Border>
20 
21                 ControlTemplate>
22                 
23             Thumb.Template>
24             <Thumb.RenderTransform>
25                 
26                 <TransformGroup>
27                     <RotateTransform CenterX="40" CenterY="40" Angle="45">RotateTransform>
28                     <ScaleTransform CenterX="40" CenterY="40" ScaleX="0.8">ScaleTransform>
29                     <TranslateTransform X="10" Y="15">TranslateTransform>
30                 TransformGroup>
31             Thumb.RenderTransform>
32         local:ThumbControl>
33     Canvas>
34 UserControl>

4. 直线

在流程图中,直线一般表示两个过程之间的连接,如下所示:

 1 <UserControl x:Class="DemoVisio.LineArrowControl"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:local="clr-namespace:DemoVisio"
 7              mc:Ignorable="d" 
 8              d:DesignHeight="450" d:DesignWidth="800">
 9     <Canvas>
10         <local:ThumbControl x:Name="s" Canvas.Left="0" Canvas.Top="0"  Width="100" Height="100" Background="AliceBlue" IsEnableInput="False">
11             <local:ThumbControl.Template>
12                 <ControlTemplate>
13                     <Grid>
14 
15                         <Line X1="0" Y1="0" X2="0" Y2="100" Stroke="Black" StrokeThickness="2" HorizontalAlignment="Center" >
16 
17                         Line>
18                         <Line X1="-5" Y1="90" X2="1" Y2="100" StrokeThickness="2" Stroke="Black" HorizontalAlignment="Center">Line>
19                         <Line X1="8" Y1="90" X2="3" Y2="100" StrokeThickness="2" Stroke="Black" HorizontalAlignment="Center">Line>
20                         <TextBox VerticalAlignment="Center" Height="30" HorizontalContentAlignment="Center" BorderThickness="0" VerticalContentAlignment="Center" MinLines="1" MaxLines="2" IsEnabled="{Binding ElementName=s, Path=IsEnableInput}" Opacity="0" Visibility="{Binding ElementName=s, Path=IsEnableInput}">TextBox>
21                     Grid>
22                 ControlTemplate>
23             local:ThumbControl.Template>
24             
25         local:ThumbControl>
26     Canvas>
27 UserControl>

主窗体

主窗体主要用于绘制流程图,分为左右两部分,左边是控件列表,右边是布局容器,如下所示:

 1 <Window x:Class="DemoVisio.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:DemoVisio"
 7         mc:Ignorable="d"
 8         Title="流程图" Height="800" Width="800" MouseDown="Window_MouseDown" Loaded="Window_Loaded">
 9     <Window.Resources>
10         <Style TargetType="TextBlock">
11             <Setter Property="HorizontalAlignment" Value="Center">Setter>
12         Style>
13     Window.Resources>
14     <Grid ShowGridLines="True">
15         <Grid.ColumnDefinitions>
16             <ColumnDefinition Width="Auto" MinWidth="150">ColumnDefinition>
17             <ColumnDefinition Width="*">ColumnDefinition>
18         Grid.ColumnDefinitions>
19         <StackPanel Grid.Column="0" x:Name="left" Orientation="Vertical">
20             <Rectangle Width="80" Height="50" Fill="AliceBlue" Stroke="Black" Margin="5" x:Name="rectangle" MouseLeftButtonDown="rectangle_MouseLeftButtonDown">Rectangle>
21             <TextBlock Text="矩形">TextBlock>
22             <Rectangle Width="100" Height="100" Fill="AliceBlue" Stroke="Black" Margin="5" x:Name="rhombus" MouseLeftButtonDown="rhombus_MouseLeftButtonDown">
23                 <Rectangle.RenderTransform>
24                     <TransformGroup>
25                         <RotateTransform CenterX="50" CenterY="50" Angle="45">RotateTransform>
26                         <ScaleTransform CenterX="50" CenterY="50" ScaleX="0.5" ScaleY="0.7">ScaleTransform>
27                     TransformGroup>
28                 Rectangle.RenderTransform>
29             Rectangle>
30             <TextBlock Text="菱形" Margin="0,5">TextBlock>
31             <Line X1="0" Y1="0" X2="0" Y2="80" Stroke="Black" StrokeThickness="2" HorizontalAlignment="Center" Margin="5" x:Name="line" MouseLeftButtonDown="line_MouseLeftButtonDown" >Line>
32             <TextBlock Text="直线">TextBlock>
33             <Ellipse Width="60" Height="60" Fill="AliceBlue" Stroke="Black" Margin="5" x:Name="circle" MouseLeftButtonDown="circle_MouseLeftButtonDown">Ellipse>
34             <TextBlock Text="圆形">TextBlock>
35         StackPanel>
36         <Canvas Grid.Column="1" x:Name="right" >
37             
38 
39         Canvas>
40     Grid>
41 Window>

当点击左边基础控件时,在右边容器中,生成新的控件。如下所示:

 1 namespace DemoVisio
 2 {
 3     /// 
 4     /// MainWindow.xaml 的交互逻辑
 5     /// 
 6     public partial class MainWindow : Window
 7     {
 8         /// 
 9         /// 控件列表
10         /// 
11         private List rightControls = new List();
12 
13         public MainWindow()
14         {
15             InitializeComponent();
16         }
17 
18         private void Window_MouseDown(object sender, MouseButtonEventArgs e)
19         {
20             //this.Focus();
21             //this.one.SetIsEnableInput(false);
22             foreach (var control in this.right.Children) {
23                 var thumb = control as ThumbControl;
24                 if (thumb != null)
25                 {
26                     thumb.SetIsEnableInput(false);
27                 }
28             }
29         }
30 
31         private void Window_Loaded(object sender, RoutedEventArgs e)
32         {
33             var width = this.right.ActualWidth;
34             var height = this.right.ActualHeight;
35 
36             int x = 0;
37             int y = 0;
38             //横线
39             while (y<height) {
40                 Line line = new Line();
41                 line.X1 = x;
42                 line.Y1 = y;
43                 line.X2 = width;
44                 line.Y2 = y;
45                 line.Stroke = Brushes.LightGray;
46                 line.StrokeThickness = 1;
47                 this.right.Children.Add(line);
48                 y = y + 10;
49             }
50             //重新初始化值
51             x = 0;
52             y = 0;
53             //竖线
54             while (x < width) {
55                 Line line = new Line();
56                 line.X1 = x;
57                 line.Y1 = y;
58                 line.X2 = x;
59                 line.Y2 = height;
60                 line.Stroke = Brushes.LightGray;
61                 line.StrokeThickness = 1;
62                 this.right.Children.Add(line);
63                 x = x + 10;
64             }
65         }
66 
67         private void rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
68         {
69             SquareControl squareControl = new SquareControl();
70             this.right.Children.Add(squareControl);
71         }
72 
73         private void rhombus_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
74         {
75             RhombusControl rhombusControl = new RhombusControl();
76             this.right.Children.Add(rhombusControl);
77         }
78 
79         private void line_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
80         {
81             LineArrowControl lineArrowControl = new LineArrowControl();
82             this.right.Children.Add(lineArrowControl);
83         }
84 
85         private void circle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
86         {
87             CircleControl circleControl = new CircleControl();
88             this.right.Children.Add(circleControl);
89         }
90     }
91 }

示例截图

示例基础截图如下所示:

备注

以上示例只是基础,功能并不完善,旨在抛砖引玉,共同学习,一起进步,希望可以对大家有所启发。

贺新郎·九日

【作者】刘克庄 【朝代】宋 湛湛长空黑。更那堪、斜风细雨,乱愁如织。 老眼平生空四海,赖有高楼百尺。 看浩荡、千崖秋色。 白发书生神州泪,尽凄凉、不向牛山滴。 追往事,去无迹。
少年自负凌云笔。到而今、春华落尽,满怀萧瑟。 常恨世人新意少,爱说南朝狂客。 把破帽、年年拈出。 若对黄花孤负酒,怕黄花、也笑人岑寂。 鸿北去,日西匿。