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

解決


しろくま  2008-04-22 07:57:17  No: 68115  IP: 192.*.*.*

.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 11:06:18  No: 68116  IP: 192.*.*.*

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

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

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

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

編集 削除
επιστημη  2008-04-22 23:40:43  No: 68117  IP: 192.*.*.*

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

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

編集 削除
YuO  2008-04-23 01:18:53  No: 68118  IP: 192.*.*.*

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

編集 削除
しろくま  2008-04-23 04:53:10  No: 68119  IP: 192.*.*.*

επιστημηさん、どらさん、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 06:00:04  No: 68120  IP: 192.*.*.*

再帰の基本。

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

編集 削除
しろくま  2008-04-24 02:50:33  No: 68121  IP: 192.*.*.*

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

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

編集 削除
επιστημη  URL  2008-04-24 06:23:21  No: 68122  IP: 192.*.*.*

↓書いてみた
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 11:12:01  No: 68123  IP: 192.*.*.*

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

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

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

編集 削除
しろくま  2008-04-27 03:29:14  No: 68124  IP: 192.*.*.*

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

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

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

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

#pragma region Windows Form Designer generated code

の下に、

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

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

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

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

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

編集 削除
επιστημη  2008-04-27 07:55:07  No: 68125  IP: 192.*.*.*

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

はい。

編集 削除
しろくま  2008-04-28 05:34:44  No: 68126  IP: 192.*.*.*

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

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


関数については、

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

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


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

編集 削除
επιστημη  URL  2008-04-28 06:19:19  No: 68127  IP: 192.*.*.*

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

ちがいます。

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

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

編集 削除