CLIで、ツリー構造を配列に読み込むには

解決


しろくま  2008-04-22 16:57:17  No: 68115

.NET2008 CLI です。

アプリケーションを閉じる時に、次回起動のため、ツリービューを配列に読み込む方法が分かりません。

再帰関数的に、自分を入れ子にする関数を作れば、なんとかなりそうに思ったのですが、そもそも関数の追加のやり方が分らない、という笑えない話になりました。
CLIの場合、「追加」→「関数の追加」に当たる項目が見当たりません。

以前、こちらで、ツリービューの表示の方法について、

    array<String^>^ data = { "ナミヘイ", 
                               "→", "サザエ", 
                                 "→", "タラ", 
                               "←", "カツオ", "ワカメ",
                           };
    TreeNode^ current = nullptr;
    TreeNode^ node;
    for each ( String^ text in data ) {
      if ( text == "→" ) {
        current = node;
      } else
      if ( text == "←" ) {
        current = current->Parent;
      } else {
        node = gcnew TreeNode(text);
        if ( current == nullptr ) treeView1->Nodes->Add(node);
        else current->Nodes->Add(node);
      }
    }

というコードを教わり、これを逆向きにすれば、自分で関数を作らなくてもいいと思ったのですが、ピンときまません。

アドバイスを頂けませんでしょうか。


どら  2008-04-22 20:06:18  No: 68116

リスト風な構造体を使ってみるとか?

typedef struct TREE
{
   /*ここに必要な要素を入れて・・・*/

   TREE *Next;         //並列した次の要素へのポインタ
   TREE *Prev;         //並列した前の要素へのポインタ
   TREE *Up;           //一つ上の階層の(親)要素へのポインタ
   TREE *Down;         //一つ下の階層の(子)要素へのポインタ
}TREE, *PTREE;

みたいな感じ。
強引すぎますかね・・・(汗)


επιστημη  2008-04-23 08:40:43  No: 68117

てかなんで配列なの?
TreeなんだからTreeのままで保存すりゃええやん、たとえばXMLとか。

# 配列でも十分やれますね。親のindexをレコード内に用意するだけ。


YuO  2008-04-23 10:18:53  No: 68118

TreeNodeはSerializableなんだから,
Listに突っ込んでシリアライズ/デシリアライズってのはだめですか。


しろくま  2008-04-23 13:53:10  No: 68119

επιστημηさん、どらさん、YuOさん、ありがとうございます。

> TreeなんだからTreeのままで保存すりゃええやん、たとえばXMLとか。

XMLは、別言語だという程度の理解なのですが、「Treeのままで保存」ということは可能なのでしょうか。

1日、あれこれ考えて、下記コードで、最初に掲載したコードの形の配列に、読み込むことができました。
長男ノードを順番に拾って行って、なくなったら弟ノードを探し、それもなくなったら親に戻って親の弟を探すようにしました。
親に戻った時、また子を探すと「ぐるぐる回し」になるので、フラグを使いました。
末尾に不必要な"←"がついてしまいますが、このままでツリーの再表示はできましたし、削除してもいいと思いました。

ただ、なんとなく「どんくさい」感じで、これでいいのでしょうか。

    array<String^>^ treelist = gcnew array<String^>(30);
    TreeNode^ current = nullptr;
    int rec = -1;
    bool upflg = false;
    current = treeView1->Nodes[0];
    treelist[++rec] = current->Text;
    while(1) {
      if ( ( !upflg )&&( current->Nodes->Count > 0 ) ) {
        treelist[++rec] = "→";
        current = current->Nodes[0];
        treelist[++rec] = current->Text;
      }
      else if ( current->NextNode != nullptr ) {
        current = current->NextNode;
        treelist[++rec] = current->Text;
          upflg = false;
      }
      else {
        current = current->Parent;
        if ( current == nullptr ) {break; }
        treelist[++rec] = "←";      
          upflg = true;
      }
    }


επιστημη  URL  2008-04-23 15:00:04  No: 68120

再帰の基本。

void 書く(対象) {
  対象をファイルに書く
  for ( 対象の子供一人一人に対し ) {
    書く(子供)
  }
}


しろくま  2008-04-24 11:50:33  No: 68121

επιστημηさん、ありがとうございます。

上記のコードでいきます。


επιστημη  URL  2008-04-24 15:23:21  No: 68122

↓書いてみた
http://cid-07c558f8e11e708f.skydrive.live.com/self.aspx/%e6%9d%b1%e6%96%b9%e6%a0%bc%e7%b4%8d%e5%ba%ab/TreeViewCPPCLI.zip


しろくま  2008-04-26 20:12:01  No: 68123

επιστημηさん、たいへんありがとうございます。

ダウンロードしました。
研究するのに少し時間がかかると思うので、先にお礼のアップをしました。

本当に、ありがとうございます。


しろくま  2008-04-27 12:29:14  No: 68124

επιστημηさん、ありがとうございます。

ご提示頂いたコードで、いきなりつまづきました。

saveGuts関数の「ひな型」は、どうやって作るのでしょうか。

「キーボードでタイプすればいい」という話になりそうですが、
アプリケーションを「Windowsフォームアプリケーションで」で作った場合、Form1.hの

#pragma region Windows Form Designer generated code

の下に、

/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。

となっていて、実際に書き換えると、アプリケーションが壊れるようです。

MFCの「メンバ関数の追加ウイザード」に代わるようなものが、ありそうに思うのです。
ツールボックスを捜してみましたが、それらしい項目は見当たりません。

επιστημηさんは、キーボードでタイプしたのでしょうか。

本題以前の問題ですが、ご指導を頂けませんでしょうか。


επιστημη  2008-04-27 16:55:07  No: 68125

> επιστημηさんは、キーボードでタイプしたのでしょうか。

はい。


しろくま  2008-04-28 14:34:44  No: 68126

επιστημηさん、ありがとうございます。

頂いたサンプルをあれこれ書き換えて実行してみて、おおまかな流れはつかみました。
もちろん、とても「理解した」とは言えないのですが。
こんなに簡単にファイルの読み書きができるのですね。

関数については、

/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。

以下を書き換えなくても、「貼り付け」られることに気付きました。

たいへんありがとうございました。


επιστημη  URL  2008-04-28 15:19:19  No: 68127

> 以下を書き換えなくても、「貼り付け」られることに気付きました。

ちがいます。

/// デザイナ サポートに必要なメソッドです。「このメソッド」の内容を
/// コード エディタで変更しないでください。

「このメソッド」を変更しなければいいのです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加