zoukankan      html  css  js  c++  java
  • 【原创】自己动手写工具----XSmartNote [Beta 2.0]

    前面的话

    在上一篇自己动手写工具----XSmartNote中,我简单介绍了这个小玩意儿的大致界面和要实现的功能,看了一下园子里的评论,评价褒贬不一,有人说“现在那么多云笔记的工具”,“极简版evernote”,我想说的是,别人的工具再好用,终究不是自己写的,其实写这个的目的,一方面是锻炼自己的技术能力,在coding的时候,或多或少会遇到一些问题,在解决这些问题的过程中,技术能力就会有所提升;另一方面,写这个东西还有自己个人原因,可以随时记录一些繁杂的知识点,通过给这些知识点打上标签,可以实现归类,那有的人会说,EverNote呢?嗯,如果你用着自己写的软件和用EverNote,哪个会更有成就感呢?好了,不多说,上图上代码!!

    这个小东西基本上实现了上一篇中列出的功能,添加note、note分类、为note加标签、根据标签对note进行筛选等。下面介绍各个功能点

    功能

    添加note

    首先在界面的右上角会提示您目前选择的树结构节点,如果新添加note就必须选择该note的所属目录(左侧的树节点),否则会因为找不到所属目录而导致添加note失败,如下图:

    这样,新增的note就会自动归类为DOT NET文件夹下咯~

     1 private void btn_Save_Click(object sender, EventArgs e)
     2  {
     3      TreeNode node = tv_Folder.SelectedNode;
     4      TipsForm tf = new TipsForm();
     5      if (node == null)
     6      {
     7          return;
     8      }
     9      if (node.Tag.ToString() == Enums.LEAVES.ToString())
    10      {
    11          //同时更新标题和内容
    12          int i = SQLHelper.UpdateContent(node.Name.ToInt(), txt_Title.Text, txt_Content.Text);
    13          //同时重新加载Treeview
    14          BuildTree(this.tv_Folder, GetFolderSet());
    15          if (i > 0)
    16          {
    17              tf.Show("保存成功!");
    18          }
    19      }
    20  }

    由于建立新note时,note的ID就确定了,所以只要根据ID来更新几个字段就可以了。所以上面是更新操作而不是插入操作。

    1  //更新标题及内容
    2  public static int UpdateContent(int id,string title,string content)
    3  {
    4      int result = -1;
    5      StringBuilder cmd = new StringBuilder();
    6      cmd.Append(string.Format("update Table_Content set Content = '{0}',Title='{1}'  where Id={2}",content,title,id));
    7      return NonQuery(cmd, result);
    8  }

    为note分类

    这个比较简单了,只要在添加的时候指定好note的所属目录就可以了,单击目录时,右侧下方的预览区会显示出该目录下的所有note,并且最上方的标签区域显示该目录下所有的note包含的标签~

    为note指定标签

    为note指定标签的过程实际上是向关联note和标签的表中加入数据的过程,这里note和标签是多对多的关系,所以需要单独建立一个关系表。

    为note加标签,是通过自定义控件LabelWithCheck的选中事件触发的,而且LabelWithCheck是在初始化时动态生成并且动态绑定事件的。

     1  public void AddLabelToLocation(FlowLayoutPanel flp, int column, string tag, int Id, bool ischecked,bool registerEvent)
     2  {
     3      //int flag = 0;
     4      int labelCount = flp.Controls.Count;
     5      int lines = labelCount / column;
     6      int left = labelCount % column;
     7      int X = (left * WIDTH) + (left + 1) * MARGIN;
     8      int Y = lines * HEIGHT + (lines + 1) * MARGIN;
     9      LabelWithCheck label = new LabelWithCheck();
    10      //注册事件
    11      if (registerEvent)
    12      {
    13          label.LabelCheckedEvent += Label_LabelCheckedEvent;
    14          //new TipsForm().Show("注册插入数据库事件");
    15      }
    16      else
    17      {
    18          label.LabelCheckedEvent += Label_LabelSelectEvent;
    19          //new TipsForm().Show("注册过滤事件");
    20      }
    21     
    22      label.BackColor = ColorTranslator.FromHtml(ColorManager.ColorConvertor(flagForPanelEdit));
    23      label.Location = new Point(X, Y);
    24      label.LabelText = tag;//存储标签名称
    25      label.Id = Id;//存储标签ID
    26      label.LabelChecked = ischecked;//选中状态
    27      flp.Controls.Add(label);
    28      flagForPanelEdit++;
    29      if (flagForPanelEdit > 19)
    30      {
    31          flagForPanelEdit = 0;
    32      }
    33  }

    下面是自定义控件LabelWithCheck的代码,重绘LabelWithCheck

     1  #region OVERRIDE
     2  protected override void OnPaint(PaintEventArgs e)
     3  {
     4      Graphics g = e.Graphics;
     5      int x = this.Width;
     6      int y = this.Height;
     7      Point leftTop = new Point(0, 0);
     8      Point rightTop = new Point(x - 1, 0);
     9      Point leftBottom = new Point(0, y - 1);
    10      Point rightBottom = new Point(x - 1, y - 1);
    11 
    12      g.DrawLine(new Pen(Color.White), leftTop, rightTop);
    13      g.DrawLine(new Pen(Color.White), leftBottom, rightBottom);
    14      g.DrawLine(new Pen(Color.White), leftTop, leftBottom);
    15      g.DrawLine(new Pen(Color.White), rightTop, rightBottom);
    16      //画上边缘
    17      for (int i = 0; i < x - 1; i += 3)
    18      {
    19          g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(i, 0, 2, 1));
    20      }
    21 
    22      //画下边缘
    23      for (int m = 0; m < x - 1; m += 3)
    24      {
    25          g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(m, y - 1, 2, 1));
    26      }
    27 
    28      //画左边缘
    29      for (int i = 0; i < y - 1; i += 3)
    30      {
    31          g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, i, 1, 2));
    32      }
    33 
    34      //画右边缘
    35      for (int i = 0; i < y - 1; i += 3)
    36      {
    37          g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(x - 1, i, 1, 2));
    38      }
    39      base.OnPaint(e);
    40  }
    41  #endregion

    定义LabelWithCheck控件的事件,为note添加标签的时候就触发这个事件,参数中包括了标签的一些信息

     1 #region EVENT
     2 public delegate void LabelWithCheckSelectedHandler(object sender, LabelWithCheckEventArgs e);
     3 public event LabelWithCheckSelectedHandler LabelCheckedEvent;
     4 private void ck_CheckedChanged(object sender, EventArgs e)//checkBox原型
     5 {
     6     if (LabelCheckedEvent != null)
     7     {
     8         LabelCheckedEvent(sender, new LabelWithCheckEventArgs(this._Id,this.LabelText));
     9     }
    10 }
    11 #endregion

     每选择一个LabelWithCheck都会动态添加该控件

    1  private void Label_LabelSelectEvent(object sender, LabelWithCheckEventArgs e)
    2  {
    3      AddLabelToLocation(flowLayoutPanel2,6,e.LabelText,e.Id,false,false); //Stack Overflow 重复绑定重复执行 形成无限循环导致
    4  }

    根据目录和标签筛选

    这一部分还没有仔细地去做,目前只是大概地处理了一下,最近实在太忙了。大概的筛选原则就是右侧上方的两个标签区域的交集,只要符合条件就会在下面的预览区域显示出来,也就是我们想要看到的结果啦~

    上面一排是所选的目录下所有note包含的所有的标签,下面是手工指定的标签,通过筛选条件的就会出现在下面的note预览区域中

    结语

    本来这个小东西早就该完成,但是中间公司又分配了些项目,没有太多的空闲时间,今天抽空把他总结出来,对自己也有个交代。在写这个玩意儿的时候,的确遇到了一些小问题,如左侧树状结构绑定同一张表中带有层级结构的数据,这是第一次接触,但是掌握了方法就OK了;还有自定义控件的动态添加和绑定事件等等。如果您有什么建议,欢迎评论,大神勿拍... ...如果觉得好玩儿,就给个赞吧~~

    2014马上过去了,不得不说时间飞快,祝各位园友在新的一年里,能够实现升职加薪,出任CTO,迎娶白富美,走向人生巅峰

     作者:悠扬的牧笛

     博客地址:http://www.cnblogs.com/xhb-bky-blog/p/4167108.html

     声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

  • 相关阅读:
    区块链技术基础
    理解数字货币
    MySQL-插入更新 ON DUPLICATE KEY UPDATE
    Flume-Failover Sink Processor 故障转移与 Load balancing Sink 负载均衡
    Flume-Replicating Channel Selector 单数据源多出口
    Flume-几种拓扑结构
    Flume-事务与传输流程
    Java-JPDA 概述
    Navicat Premium
    Flume-Taildir Source 监控目录下多个文件的追加
  • 原文地址:https://www.cnblogs.com/xhb-bky-blog/p/4167108.html
Copyright © 2011-2022 走看看