非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

C#で付箋紙を作る(第四回目) データの数だけ付箋紙を起動する

      2017/07/17

前回の記事はこちら。

 

前回はXMLファイルから各パラメーター(画面上の位置、付箋紙のサイズ、背景色、フォント、表示するテキスト)を読み込んで付箋紙に反映させました。

前回はあくまでデータの1つめだけを反映させましたが、今回は複数データがあった場合にその数だけ付箋紙を生成する方法を紹介します。

 

今回の完成形

起動すると以下のようにデータの数だけ付箋紙が生成されます。それぞれのパラメータを反映させています。

 

前回は都合上、新規作成機能を排除していましたが、今回はデフォルト値で新規に付箋紙が生成されるようにしました。

 

あとは、以下についてもパラメーターが更新されるようにしました。

  • 文字の編集
  • 付箋紙サイズの変更
  • 付箋紙の移動時の位置

[ad#top-1]

XMLファイル

前回と違い今回は複数のデータが入っています(Stickyタグ)。起動時にこの数分だけ付箋紙を生成させます。

<?xml version="1.0" encoding="utf-8"?>
<Stickys xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Sticky>
    <text>テスト付箋紙aaa</text>
    <width>214</width>
    <height>51</height>
    <top>143</top>
    <left>1022</left>
    <red>255</red>
    <green>200</green>
    <blue>200</blue>
    <font-family>Meiryo UI</font-family>
    <font-size>14</font-size>
  </Sticky>
  <Sticky>
    <text>テスト付箋紙2</text>
    <width>200</width>
    <height>80</height>
    <top>39</top>
    <left>1041</left>
    <red>200</red>
    <green>200</green>
    <blue>255</blue>
    <font-family>Meiryo UI</font-family>
    <font-size>10</font-size>
    </Sticky>
  <Sticky>
    <text>テスト付箋紙3</text>
    <width>100</width>
    <height>80</height>
    <top>222</top>
    <left>1073</left>
    <red>200</red>
    <green>255</green>
    <blue>200</blue>
    <font-family>HGP創英角ポップ体</font-family>
    <font-size>12</font-size>
  </Sticky>
</Stickys>
 

 

追加したソースコード

今回加えたのはこのアプリにコマンドライン引数を渡し、それを数値変換してインスタンス変数indexに入れています。(引数ナシまたは引数が数値変換できない場合はindex=0)

indexに入れた数値がそのままXMLデータの要素番号になります。(index==0: 1個めのデータ)

また、新規作成はindexを-1としました。

this.index=0;
if(args.Length &gt; 0 &amp;&amp; int.TryParse(args[0], out index)){ }
 

 

//もし新規作成(index==-1)なら新規作成&amp;indexを最後の要素Noに
if(index==-1){
  this.addNewSticky();
  index = list.DataList.Count - 1;
}
 

 

以下のように最初の起動時(index==0)にデータが複数存在すれば、自分以外のデータの数だけアプリを起動します。引数はデータの要素No.です。※ループ内に1秒だけ待機させていますがこれがないとうまく起動しない。

//もしデータが複数あったらデータの数だけ起動(indexを渡す)
if(index==0 &amp;&amp; list.DataList.Count&gt;1){
  for(int i=1; i&lt;list.DataList.Count; i++){
    System.Diagnostics.Process.Start("sticky.exe", i+"");
    System.Threading.Thread.Sleep(1000);
  }
}
 

 

新規作成時はコマンドライン引数に-1を渡し、アプリを起動します。

if(e.ClickedItem.Name=="newBtn") {
  System.Diagnostics.Process.Start("sticky.exe", "-1");
}
 

 

あといろいろ追加点がありますが、重要なところはこんなところです。

 

ソースコード全文

ソースコード全文です。これをコピペしてコンパイルすれば今回のものができます。

using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using System.Collections.Generic;
class Sticky{
  static void Main(string[] args){
    Application.Run(new StickyNote(args));
  }
}

partial class StickyNote : Form{
  private int index;
  private Point mousePoint;
  private Label label;
  private TextBox textBox;
  private StickyList list;

  public StickyNote(string[] args){
    this.index=0;
    if(args.Length > 0 && int.TryParse(args[0], out index)){ }

    this.StartPosition = FormStartPosition.Manual;
    this.Text = "付箋紙";
    this.FormBorderStyle = FormBorderStyle.None;
    this.ShowInTaskbar = false;

    this.MouseDown += new MouseEventHandler(MouseDowned);
    this.MouseMove += new MouseEventHandler(MouseMoved);
    this.DoubleClick += new EventHandler(DoubleClicked);

    //xmlファイルから読み込み。データ数を取得
    this.readData();
    if(list.DataList.Count==0) this.addNewSticky();
    //もし新規作成(index=-1)なら新規作成&indexを最後の要素Noに
    if(index==-1){
      this.addNewSticky();
      index = list.DataList.Count - 1;
    }

    //付箋紙生成(作成するデータ番号=index)
    this.Width = list.DataList[index].Width;
    this.Height = list.DataList[index].Height;
    this.Location = new Point(list.DataList[index].Left, list.DataList[index].Top);
    this.setComponents();
    //もしデータが複数あったらデータの数だけ起動(indexを渡す)
    if(index==0 && list.DataList.Count>1){
      for(int i=1; i<list.DataList.Count; i++){
        System.Diagnostics.Process.Start("sticky.exe", i+"");
        System.Threading.Thread.Sleep(1000);
      }
    }
  }

  //新規作成時のデフォルト値
  private void addNewSticky(){
    StickyData sticky = new StickyData();
    sticky.Text = " ";
    sticky.Width = 200;
    sticky.Height = 80;
    sticky.Top = 300;
    sticky.Left = 300;
    sticky.Red = 255;
    sticky.Green = 200;
    sticky.Blue = 200;
    sticky.FontFamily = "Meiryo UI";
    sticky.FontSize = 10;

    list.DataList.Add(sticky);
    this.saveData(); //保存
  }

  private void DoubleClicked(object sender, EventArgs e){
    if(this.FormBorderStyle == FormBorderStyle.None){
      this.FormBorderStyle = FormBorderStyle.Sizable;
      this.ControlBox = false;
      this.Controls.Remove(label);
      this.Controls.Add(textBox);
      textBox.Text = label.Text;
    }else{
      this.FormBorderStyle = FormBorderStyle.None;
      this.Controls.Remove(textBox);
      this.Controls.Add(label);
      label.Text = textBox.Text;
      //サイズとテキストを記憶→保存
      list.DataList[index].Width = this.Width;
      list.DataList[index].Height = this.Height;
      list.DataList[index].Text = label.Text;
      this.saveData();
    }
  }

  private void popClicked(Object sender, ToolStripItemClickedEventArgs e) {
    if(e.ClickedItem.Name=="closeBtn") this.Close();
    if(e.ClickedItem.Name=="newBtn") {
      System.Diagnostics.Process.Start("sticky.exe", "-1");
    }
  }

  private void readData(){
    FileStream file = new FileStream("sticky.xml", FileMode.Open);
    XmlSerializer serializer = new XmlSerializer(typeof(StickyList));
    list = (StickyList)serializer.Deserialize(file);
    file.Close();
    //テキストの改行処理
    for(int i=0; i<list.DataList.Count; i++){
      list.DataList[i].Text = list.DataList[i].Text.Replace("\n", "\\n");
      list.DataList[i].Text = list.DataList[i].Text.Replace("\r", "\\r");
    }
  }

  private void saveData(){
    //テキストの改行処理
    for(int i=0; i<list.DataList.Count; i++){
      list.DataList[i].Text = list.DataList[i].Text.Replace("\n", "\\n");
      list.DataList[i].Text = list.DataList[i].Text.Replace("\r", "\\r");
    }

    //自分のデータのみを別のクラスに避難
    StickyData sticky = list.DataList[index];
    //読み直し
    this.readData();
    //自分のデータのみを入れ替え
    list.DataList[index] = sticky;
    //保存
    FileStream stream = new FileStream("sticky.xml", FileMode.Create);
    StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
    XmlSerializer serializer = new XmlSerializer(typeof(StickyList));
    serializer.Serialize(writer, list);
    writer.Flush();
    writer.Close();
  }

  private void setComponents(){
    Font font = new Font(list.DataList[index].FontFamily, list.DataList[index].FontSize);

    label = new Label(){
      Dock = DockStyle.Fill,
      Font = font,
      BorderStyle = BorderStyle.FixedSingle,
      Parent=this,
      //以下パラメーター設定
      Text = list.DataList[index].Text,
      BackColor = Color.FromArgb(list.DataList[index].Red, list.DataList[index].Green, list.DataList[index].Blue),
    };
    label.DoubleClick += new EventHandler(DoubleClicked);
    label.MouseDown += new MouseEventHandler(MouseDowned);
    label.MouseMove += new MouseEventHandler(MouseMoved);
    label.MouseUp += new MouseEventHandler(MouseUped);

    textBox = new TextBox(){
      Dock = DockStyle.Fill,
      Font = font,
      Multiline = true,
      WordWrap = false,
      //以下パラメーター設定
      Text = list.DataList[index].Text,
      BackColor = Color.FromArgb(list.DataList[index].Red, list.DataList[index].Green, list.DataList[index].Blue),
    };
    textBox.DoubleClick += new EventHandler(DoubleClicked);

    ToolStripMenuItem newItem = new ToolStripMenuItem(){
      Text = "新規付箋紙",
      Name = "newBtn",
    };
    ToolStripMenuItem closeItem = new ToolStripMenuItem(){
      Text = "この付箋紙を捨てる",
      Name = "closeBtn",
    };

    ContextMenuStrip pop = new ContextMenuStrip();
    pop.Items.AddRange(new ToolStripItem[] {
      newItem, new ToolStripSeparator(), closeItem
    });
    pop.ItemClicked += new ToolStripItemClickedEventHandler(popClicked);

    this.ContextMenuStrip = pop;
  }

  //マウスのボタンがアップしたとき
  private void MouseUped(object sender, System.Windows.Forms.MouseEventArgs e){
    list.DataList[index].Top = this.Location.Y;
    list.DataList[index].Left = this.Location.X;
    this.saveData();
  }

  //マウスのボタンが押されたとき
  private void MouseDowned(object sender, System.Windows.Forms.MouseEventArgs e){
    if ((e.Button & MouseButtons.Left) == MouseButtons.Left){
       //位置を記憶する
      mousePoint = new Point(e.X, e.Y);
    }
  }

  //マウスが動いたとき
  private void MouseMoved(object sender, System.Windows.Forms.MouseEventArgs e){
    if ((e.Button & MouseButtons.Left) == MouseButtons.Left){
      this.Location = new Point(
        this.Location.X + e.X - mousePoint.X,
        this.Location.Y + e.Y - mousePoint.Y);
      }
    }
  }

[XmlRoot("Sticky")]
public class StickyData{
  [XmlElement("text")]
  public string Text { get; set; }
  [XmlElement("width")]
  public int Width { get; set; }
  [XmlElement("height")]
  public int Height { get; set; }
  [XmlElement("top")]
  public int Top { get; set; }
  [XmlElement("left")]
  public int Left { get; set; }
  [XmlElement("red")]
  public int Red { get; set; }
  [XmlElement("green")]
  public int Green { get; set; }
  [XmlElement("blue")]
  public int Blue { get; set; }
  [XmlElement("font-family")]
  public string FontFamily { get; set; }
  [XmlElement("font-size")]
  public int FontSize { get; set; }
}

[XmlRoot("Stickys")]
public class StickyList{
  [XmlElement("Sticky")]
  public List<StickyData> DataList { get; set; }
}
 

 

関連記事

 

[ad#ad-1]

スポンサーリンク

 - C#応用編