【原創】自己動手寫工具----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

 聲明:本博客原創文字只代表本人工作中在某一時間內總結的觀點或結論,與本人所在單位沒有直接利益關系。非商業,未授權貼子請以現狀保留,轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM