C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: myTreeNodeをクリップボードへ


(過去ログ 89 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■53147 / inTopicNo.1)  myTreeNodeをクリップボードへ
  
□投稿者/ 直 (1回)-(2010/09/04(Sat) 10:54:38)

分類:[C#] 

VS2008 C#

TreeNodeだとクリップボードにコピーできるのですが、myTreeNodeだとエラーになります。どこがいけないのでしょうか。教えて下さい。

public Form1()
{
InitializeComponent();
成功();
失敗();
}

void 成功()
{
// クリップボードにセット
DataFormats.Format myF = DataFormats.GetFormat("myF");
TreeNode tn1 = new TreeNode();
tn1.Text = "あいうえお";
DataObject obj = new DataObject();
obj.SetData(myF.Name, tn1);
Clipboard.SetDataObject(obj);

// クリップボードから取り出し
DataFormats.Format fm = DataFormats.GetFormat("myF");
IDataObject dt = Clipboard.GetDataObject();
TreeNode tn2 = (TreeNode)dt.GetData(fm.Name);
if (tn2 != null)
Console.WriteLine("成功 = {0} ", tn2.Text);
}

void 失敗()
{
// クリップボードにセット
DataFormats.Format myF = DataFormats.GetFormat("myF");
MyTreeNode tn1 = new MyTreeNode();
tn1.Text = "あいうえお";
DataObject obj = new DataObject();
obj.SetData(myF.Name, tn1);
Clipboard.SetDataObject(obj);

// クリップボードから取り出し
DataFormats.Format fm = DataFormats.GetFormat("myF");
IDataObject dt = Clipboard.GetDataObject();
MyTreeNode tn2 = (MyTreeNode)dt.GetData(fm.Name);

if (tn2 != null)     // <<<--- ここでエラー
Console.WriteLine("失敗 = {0} ", tn2.Text);
}

//[Serializable]
public class MyTreeNode : TreeNode
{
public string 題;
}

引用返信 編集キー/
■53152 / inTopicNo.2)  Re[1]: myTreeNodeをクリップボードへ
□投稿者/ Hongliang (699回)-(2010/09/04(Sat) 14:23:12)
2010/09/04(Sat) 14:23:55 編集(投稿者)

例外が出るならそのメッセージぐらいは書きましょう。

基底クラスである TreeNode は ISerializable インターフェイスを実装しているので、派生クラスもこのインターフェイスの作法に則った記述が必要です。
基本的には
・(SerializationInfo, StreamingContext) の二つの引数を取るコンストラクタ
・ISerializable のメンバである GetObjectData(SerializationInfo, StreamingContext)
の二つを実装します。
ただし、TreeNode は GetObjectData を明示的実装し、派生クラスには代わりに Serializable メソッドをオーバーライドすることを要求しています(ISerializable の再実装は不要)。

Serializable メソッドでは、基底のメソッドを呼び出した上で、自分自身の保存すべきプロパティ(この MyTreeNode なら "題" がそうですね)を SerializationInfo に AddValue メソッドで保存します。
(SerializationInfo, StreamingContext) コンストラクタでは、基底の同じ引数のコンストラクタを呼んだ上で、SerializationInfo から GetValue や GetString などを使って自分自身の復元すべきプロパティに値を設定します。
引用返信 編集キー/
■53188 / inTopicNo.3)  Re[2]: myTreeNodeをクリップボードへ
□投稿者/ 直 (2回)-(2010/09/06(Mon) 10:22:59)
Hongliang さん
ご丁寧なご指導ありがとうございます。
ただ、非常に高度な内容なので、MyTreeNodeへの値の与え方(tn1.題 のセット方法)がわかりません。もう一度ご指導下さい。

public Form5()
{
InitializeComponent();
失敗();
}
void 失敗()
{
// クリップボードにセット
DataFormats.Format myF = DataFormats.GetFormat("myF");
//SerializationInfo si = new SerializationInfo();  // <<<--- MyTreeNodeへの値の与え方がわからない
MyTreeNode tn1 = new MyTreeNode();
tn1.題 = "あいうえお";
DataObject obj = new DataObject();
obj.SetData(myF.Name, tn1);
Clipboard.SetDataObject(obj);

// クリップボードから取り出し
DataFormats.Format fm = DataFormats.GetFormat("myF");
IDataObject dt = Clipboard.GetDataObject();
MyTreeNode tn2 = (MyTreeNode)dt.GetData(fm.Name); 
if (tn2 != null)           // <<<--- ここでNullになってしまう。
Console.WriteLine("失敗 = {0} ", tn2.題);
}

public class MyTreeNode : TreeNode  // , ISerializable
{
public string 題;

public MyTreeNode() { }

public MyTreeNode(SerializationInfo si, StreamingContext context)
{
this.題 = si.GetString("題");
}

public void GetObjectData(SerializationInfo si, StreamingContext context)
{
//base.GetObjectData(si, context);
si.AddValue("題", this.題);
}
}



引用返信 編集キー/
■53193 / inTopicNo.4)  Re[3]: myTreeNodeをクリップボードへ
□投稿者/ Hongliang (703回)-(2010/09/06(Mon) 11:19:41)
> // クリップボードにセット
> DataFormats.Format myF = DataFormats.GetFormat("myF");
> //SerializationInfo si = new SerializationInfo();  // <<<--- MyTreeNodeへの値の与え方がわからない
> MyTreeNode tn1 = new MyTreeNode();
> tn1.題 = "あいうえお";
> DataObject obj = new DataObject();
> obj.SetData(myF.Name, tn1);
> Clipboard.SetDataObject(obj);
ここで何かする設定する必要はありません。
TreeNode をクリップボードに設定するときだってわざわざ SerializationInfo は作らないでしょう?
そこら辺は Clipboard.SetDataObject する際に内部で勝手にやることです。

> IDataObject dt = Clipboard.GetDataObject();
> MyTreeNode tn2 = (MyTreeNode)dt.GetData(fm.Name); 
> if (tn2 != null)           // <<<--- ここでNullになってしまう。 
DataObject.GetData はデシリアライズに失敗すると null になります。
コンストラクタで例外が出たときとか。

> public MyTreeNode(SerializationInfo si, StreamingContext context)
前回こう書きました。
> SerializationInfo, StreamingContext) コンストラクタでは、基底の同じ引数のコンストラクタを呼んだ上で

> public void GetObjectData(SerializationInfo si, StreamingContext context)
前回こう書きました。
> 派生クラスには代わりに Serializable メソッドをオーバーライドすることを要求しています
> Serializable メソッドでは、基底のメソッドを呼び出した上で

引用返信 編集キー/
■53195 / inTopicNo.5)  Re[4]: myTreeNodeをクリップボードへ
□投稿者/ 直 (3回)-(2010/09/06(Mon) 15:10:55)
No53193 (Hongliang さん) に返信

ご指導下さりありがとうございます。

>>SerializationInfo, StreamingContext) コンストラクタでは、基底の同じ引数のコンストラクタを呼んだ上で
public MyTreeNode(SerializationInfo si, StreamingContext context):base(si, context)
{
this.題 = si.GetString("題");
}

>>派生クラスには代わりに Serializable メソッドをオーバーライドすることを要求しています
>>Serializable メソッドでは、基底のメソッドを呼び出した上で
protected override void Serialize(SerializationInfo si, StreamingContext context)
{
base.Serialize(si, context);
si.AddValue("題", this.題);
}

以上の記述で良かったでしょうか? 見よう見まねで書いてみました。





引用返信 編集キー/
■53215 / inTopicNo.6)  Re[5]: myTreeNodeをクリップボードへ
□投稿者/ 直 (4回)-(2010/09/07(Tue) 09:54:41)
Hongliang さん
無事成功しました。
>(ISerializable の再実装は不要)
を早とちりして、[Serializable]を消していました。
Hongliangさんがいなかったら、自分では到底たどりつけない
ハイレベルなものでした。本当にありがとうございました。
心より感謝しています。
以下に成功ソースを掲載致します。


public Form1()
{
InitializeComponent();
MyTreeNode復元();
}

void MyTreeNode復元()
{
// クリップボードにセット
DataFormats.Format myF = DataFormats.GetFormat("myF");
MyTreeNode tn1 = new MyTreeNode();
tn1.題 = "あいうえお";
DataObject obj = new DataObject();
obj.SetData(myF.Name, tn1);
Clipboard.SetDataObject(obj);

// クリップボードから取り出し
DataFormats.Format fm = DataFormats.GetFormat("myF");
IDataObject dt = Clipboard.GetDataObject();
MyTreeNode tn2 = (MyTreeNode)dt.GetData(fm.Name);
if (tn2 != null)
Console.WriteLine("復元成功 = {0} ", tn2.題);
}

[Serializable]
public class MyTreeNode : TreeNode
{
public string 題;

public MyTreeNode() { }

public MyTreeNode(SerializationInfo si, StreamingContext context):
base(si, context)
{
this.題 = si.GetString("題");
}

protected override void Serialize(SerializationInfo si, StreamingContext context)
{
base.Serialize(si, context);
si.AddValue("題", this.題);
}
}
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -