直列つなぎ。 -とある発達障害者の記録

知識と知識を繋ぐためのblog。 広汎性発達と診断されました。ぜんぜん役に立ってないけど。月収13万円、家賃4万円で生活するひつじ人間。

【C#】自身をコピーした上でデータを受け渡すフォーム

カウンタ
ブログパーツ


 更新履歴 
  17/06/17
   一部の処理を修正。問題点追記。
   6/19
   サンプルを見直してフォームクローズ用変数の定義。
   フォームを閉じるまでアプリを終了させない処理を追記   


 フォーム間でデータの受け渡しをクールに行う。
  を参考に自身をコピーした上でデータを受け渡すフォームを作成した。
 Formに重複しないIDを割り当てる為の処理。
 

 作成中の付箋ソフトFakeSticky用。  

  尚、 InvisibleForm クラスを追加し、同名の名前空間に入れるものとする(この場合は FormCount_and_data)

      public InvisibleForm()
        {
   //コンストラクタ
            Form1 frm = new Form1(i);
            frm.Show();
       
        }


  具体的なコードは 
[C#] 起動時にメインフォームを非表示にする
  更に ALT+TABのメニューに表示させなくする方法(C#)  の追加で完全な不可視に。
   いずれも魚拓取得済みである。



using System;
using System.Windows.Forms;

namespace FormCount_and_data   //好きな名前で
{
    public class Program
    {

        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        ///
        [STAThread]
        static void Main()
        {
            //初期引数
            int i=0;

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);


     //不可視フォーム
              InvisibleForm  f = new InvisibleForm();
            Application.Run(new InvisibleForm(i));
        }
    }

}



 using System;
using System.Windows.Forms;

namespace FormCount_and_data
{
    public partial class Form1 : Form
    {
        public int FormCountValues; //自身から受け取った引数
        static int ReturnValue;   //自身に返す戻り値  staticフィールドに
       // public int ReturnValue;      //これだと、変数が共有されず、新しいFormのインスタンスと既存のFormインスタンスが混在する。 下端の動画参照。
    static int ClosedFormCount; //フォームを閉じた数
      


        public Form1(int argu) //Form自身の起動に対し引数を割り当てる
        {
            InitializeComponent();



            FormCountValues; = argu;
            //引数を自身に渡す

        
            textBox1.Text = FormCountValues;.ToString(); ;

              FormCountValues++;
        }

      
        private void button1_Click(object sender, EventArgs e)
        {
       


            FornCountValues++;


//処理結果を代入
 FormCountValues = FormCount(FormCountValues);

        
        }

    /// <summary>
/// iは自身から受け取る引数であり、自動的に割り当てられる
/// この場合はreturnValue
/// </summary>
/// <param name="i">Formから渡されるパラメータ</param>
/// <returns></returns>
        public static int FormCount(int i)  ////iは自身から受け取る引数であり、自動的に割り当てられる
        {
         Form1 f = new Form1(receiveCount);
f.Show();

///隣に表示
f.Top = Top;
f.Left = Width + Left;

f.Name = textBox1.Text;

f.ReturnValue = receiveCount;
//自身の戻り値に値を渡す


//戻り値専用変数

return f.ReturnValue++; //arguに自動的に割り当て?

        }


  
/// <summary>
/// フォーム内の×ボタン判定
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
const int WM_NCLBUTTONDOWN = 0xA1;
const int HTCLOSE = 20;
if (m.Msg == WM_NCLBUTTONDOWN)
{
switch (m.WParam.ToInt32())
{

case HTCLOSE:
//閉じるボタンの上でマウスの左を押したとき。


//ここでXボタンが押されたかコンテキストメニューからのものかを判定


//閉じられた子フォームの数+1
ClosedFormCount++;

// すべてのフォームが閉じられたら
if (FormCountValues < ClosedFormCount)
{
//リセット
ClosedFormCount = 0;
// アプリケーション終了
Application.Exit();
}

break;
}
}
base.WndProc(ref m);
}
    }
}



 実行結果
   FormIncliment.jpg


 ・・・・正直言ってこれだけでは使い物にならない印象。
 問題点
  1. 同名のFormに対し、どう区別を付けてアクセスするか?

 考えられる方法
  a. 上記処理を行った上でnameプロパティを変えてやる
    textBox1.Text = Name = "Form_" + argumentValues.ToString();

          -名前を変えただけのサブフォームにアクセス出来るか?


 
   2. 別の子フォームから自身を複製すると、同じIDのFormが複数出来てしまう
  textBox1.text = 1 や 3 の子フォームが複数存在してしまう。
    → Form間で共有されるべき変数が同期されない
    → staticフィールドにするとグローバル変数として扱われる。どうもヒントを見逃していたのもあるようだ・・・・。

  3. 修正したものの、途中でFormを閉じるなどして数を減らすと依然として重複が発生する。

→とりあえずサンプルを見直してフォームを閉じた数をカウント。
 └ 連番が際限なく増える。 Listクラスなどで連番の抜けを探し、抜け番に優先して割り当てるなどといった処理を考えたい。  
 


 考えられる方法
   a.DataBindingsで管理。  → 不慣れなので幾つかサンプルを漁る必要が。
   一応は可能性のある解決策。
        a.XMLで設定情報を保存。どーもこれが一番スマートなようで。

   b.Form間共通の変数を定義 → 同様の問題が起こった。 既に開かれているFormについては同期されない。 → staticにすることで解決
   
  


試したこと
 共通変数 Program.csのメンバに以下を定義
      public static int FormInt;

     必ず静的メンバであることが必要らしい
 
  ジェネリック版も試した  static public List <int> Formint = new List<int>();
   
 処理:
            Program.FormInt = FormCountValues;
            // 変数を外部で共有する

    //ジェネリックでは Formint.Countなどとしてみた。
 
  ・・・・結局は同様の問題が発生。これらの変数を定義してみても、既に開かれたフォームに関しては同期が行われない。やはりDataBindingが必要だと思われる。
  プロパティを定義してもおそらく同様の問題が発生する。


 解法:https://teratail.com/questions/79854 で質問したところ、ReturnValueをインスタンスフィールドではなくスタティックフィールドにすれば解決するとのこと。
 すげーあっさり直った・・・・orz。
  

 動画 修正前
   


  修正後の挙動 重複しない。
     
   


 いやホントさ、付箋ソフトってどういう処理になってんの???
 blogだって碌なのないしさ。海外も読みやすいのは殆どない。徒労。

 
 XMLでデータ管理を行うのが一番確実なようだった。
 同様のアプリを見ると。 今後はXMLの扱いを学びたい。
 
関連記事
スポンサーサイト

 【C#】Fakesticky

 Fakesticky

0 Comments

Leave a comment