C#のforeachで複数DLLの情報を集める際に発生する問題と解決方法

このQ&Aのポイント
  • C#のforeachを使って複数のDLLの情報を一つのコレクションに集める際に、次のコレクションに移ると最初のコレクションの情報が上書きされてしまうという問題が発生しています。
  • さらに、画像をクリックした際に作成されるボタンの削除がうまくいかず、textBoxだけが削除されて作り直されてしまうという問題もあります。
  • さらにさらに、どちらのボタンを押してもtextBoxにはDLL2が入力されてしまいます。この問題の解決策についても考えています。
回答を見る
  • ベストアンサー

C#のforeachに苦しめられてます。

foreachで複数のDLLの情報をもってきて、一つのコレクションに集めます。集めたコレクションの次のコレクションに移ると最初のコレクションの情報が上書きされてしまうのが悩みです。 foreach (var e in dll) { var PictureBox1 = new PictureBox();//画像が表示される場所はずれて重ならなくなっている。 PictureBox1.Click += (s, e) => { 既につくられているtextBoxの削除("textBoxの名前");//名前指定で削除できる自作関数 既につくられているbuttonの削除("buttonの名前"); 関数(); } } DLL1.dll 関数(){   textBoxの作成(); buttonの作成();   クリックしたときのイベント{    textBox.Text="DLL1";   } } DLL2.dll 関数(){   textBoxの作成(); buttonの作成();   クリックしたときのイベント{    textBox.Text="DLL2";   } } どちらの画像(PictureBox1)をおしても、ボタンとtextboxが作られますが、なぜか、2回目の画像のクリックではボタンの削除がうまくいかず、textBoxだけが削除され作り直されます。 さらに、どちらのボタンを押してもtextboxにはDLL2が入力されてしまいます。 どのように解決したらよいでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

うーん、具体的なロジックが不明なので何とも言えませんが、 DirectoryCatalog()で指定してたディレクトリに入っているDLLが古かったりしませんか? DLLをコンパイルしているだけで、DirectoryCatalog()のディレクトリ内にコピーし忘れてるとか。 関数();は、PictureBox1がクリックされた際に実行されるものであると思われますが、 そのDLL内部の関数()内で、『クリックしたときのイベント』というのがあるのも不可解ですが、 前回の流れ的に、ボタンをクリックした時のイベントでしょうかね?? テキトーに作成したところ、問題なく動きますので、コピー忘れなどの安直なミスだと 思うんですが・・・。 【I/F】 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace MefIf { public interface MefIf { string picturebox1url(); void viewControls(Control c); } } 【AddIn1】 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.ComponentModel.Composition; using MefIf; namespace Mef1 { [Export(typeof(MefIf.MefIf))] public class Mef1 : MefIf.MefIf { public string picturebox1url() { return @"C:\1.png"; } TextBox t = null; Button b = null; public void viewControls(Control c) { if (t != null) { c.Controls.Remove(t); } if (b != null) { c.Controls.Remove(b); } t = new TextBox(); t.Left = 100; t.Width = 100; t.Top = 100; t.Height = 20; c.Controls.Add(t); b = new Button(); b.Left = 100; b.Width = 100; b.Top = 130; b.Height = 20; b.Text = "Click!"; c.Controls.Add(b); b.Click += (s, e) => { t.Text = "DLL1"; }; } } } 【AddIn2】 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.ComponentModel.Composition; using MefIf; namespace Mef2 { [Export(typeof(MefIf.MefIf))] public class Mef2 : MefIf.MefIf { public string picturebox1url() { return @"C:\2.png"; } TextBox t = null; Button b = null; public void viewControls(Control c) { if (t != null) { c.Controls.Remove(t); } if (b != null) { c.Controls.Remove(b); } t = new TextBox(); t.Left = 200; t.Width = 100; t.Top = 100; t.Height = 20; c.Controls.Add(t); b = new Button(); b.Left = 200; b.Width = 100; b.Top = 130; b.Height = 20; b.Text = "Click!"; c.Controls.Add(b); b.Click += (s, e) => { t.Text = "DLL2"; }; } } } 【Form】 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using MefIf; namespace WindowsFormsApplication2 { public partial class Form1 : Form { private DirectoryCatalog catalog; private CompositionContainer container; [ImportMany] private List<MefIf.MefIf> addins; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { catalog = new DirectoryCatalog("plugins"); container = new CompositionContainer(catalog); container.ComposeParts(this); } private void button1_Click(object sender, EventArgs e) { foreach (var addin in addins) { var PictureBox1 = new PictureBox(); if (addin.ToString() == "Mef1.Mef1") { PictureBox1.Left = 10; PictureBox1.Width = 100; PictureBox1.Top = 10; PictureBox1.Height = 80; } else { PictureBox1.Left = 200; PictureBox1.Width = 100; PictureBox1.Top = 10; PictureBox1.Height = 80; } PictureBox1.ImageLocation = addin.picturebox1url(); PictureBox1.Click += (s, ex) => { addin.viewControls(this); }; this.Controls.Add(PictureBox1); } } } }

satisfied999
質問者

お礼

ありがとうございます。なんとかなりました☆ 感謝です。

satisfied999
質問者

補足

返信ありがとうございます。 私が作成したツールをアップロードしてみました http://1drv.ms/1nXI0l1 また、 状況の動画を作成してみました。 http://youtu.be/LMcpGo3OWPE 書いていただいたソースはまだ試していないので後ほど試してみたいと思います。

その他の回答 (1)

回答No.1

どちらもDLL2.dll内の関数()が呼び出されているということはありませんか? foreach()回している変数eの内容がよくわからないのと、関数()をどのように呼び出しているのでしょうか?

satisfied999
質問者

補足

eにはMEFを使ってDLLの内容をコンテナに入れています。 >>どちらもDLL2.dll内の関数()が呼び出されているということはありませんか? PictureBox1で表示される画像の指定アドレスもDLLからよびだしていますので、同じものが読み込まれているということはないです。 foreach (var e in dll) { var PictureBox1 = new PictureBox(); PictureBox1.ImageLocation = e.picturebox1url();// PictureBox1.Click += (s, e) => { このような形です。 関数もMEFをつかって、DLL⇒インターフェイス⇒メインというかたちで呼び出しています。

関連するQ&A

  • C# 動的に読み込んだコントロールの削除

    C#にて動的に読み込んだ不特定多数のコントロールを削除する正しい手順は どのような物でしょうか。 MSDNによるとコンテナに読み込んだコントロールをFlowLayoutPanel.Clear()で クリアするとメモリリークにつながるため、Dispose()をしろとあります。 動的に作成したコントロールが不特定多数のため、Foreach文をつかい FlowLayoutPanel.Controlsで確認できた物をDispose()しましたが、偶数indexの コントロールしか削除されませんでした。 まぁ、これはなんとなく分かるのですが、では、正しくすべてのコントロールを 削除するにはどうしたら良いのか分かりません。 ご教示のほど、よろしくお願いいたします。 確認コード(空のForm1_Loadに貼り付け) ※現象を再現させるためのサンプルで意味はありません // コントロール配置用のコンテナ FlowLayoutPanel panel = new FlowLayoutPanel(); panel.Dock = System.Windows.Forms.DockStyle.Fill; this.Controls.Add(panel); // テストコントロール追加ボタン Button create = new Button(); create.Size = new Size(50, 25); create.Text = "create"; create.Click += (ss, ee) => { for (int i = 0; i < 100; i++) { TextBox text = new TextBox(); text.Size = new Size(50, 25); text.Text = i.ToString(); panel.Controls.Add(text); } }; panel.Controls.Add(create); // コントロール削除ボタン Button delete = new Button(); delete.Size = new Size(50, 25); delete.Text = "delete"; delete.Click += (ss, ee) => { foreach (var control in panel.Controls) { if (control is TextBox) { ((TextBox)control).Dispose(); } } }; panel.Controls.Add(delete);

  • 複数のボタンを、プロパティを引数に、ひとつのイベントに飛ばしたい

    VB2005 Expressを使っています。 デザインでButton1、Button2、 Button25までコピーペーストで 配置し、名称はそのままButton1からButton25とします。 TextもそのままButton1からButton25とします。 テキストボックスをひとつだけ作り名称は、TextBox1で TextBox1のテキストは、空白とします。 各ボタンを押したら、そのボタンの名称、 または そのボタンのTextでも構いません Tagでもいいです。 (例="Button5")を、 TextBox1に表示するプログラムを作る場合 Button1をクリックした時のPrivateSub(みたいなやつ)   TextBox1.Text="Button1"  End Sub を25回、書けばコードが長く なってしまいますが、 できれば   For a=1 to 25 When Click Button(a) Then (みたいな感じ) TextBox1.Text="Button"& a Next こういう、[!感じ] でコードを短くしたいのですが、 よい方法があれば教えてください。

  • ボタン操作

    VC++2008ExpressEditionを使用してプログラムを作成しています。 Windowsフォームアプリケーションを作成し、そこに、TextBoxとButtonを放り込み、ボタンを押すと以下のようなコードが実行されるようにしました。   System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {     static bool flug=false;     if(flug)return;     flug=true;     button1->Enabled=false;     button1->Text=L"実行中";     button1->Update();     int i;     for(i=0;i<200;i++){       int t=clock();       while(10>clock()-t);       textBox4->Text+=L"aaraeaewa"+i+L"\r\n";       textBox4->SelectionStart = textBox4->Text->Length;       textBox4->ScrollToCaret();     }     button1->Enabled=true;     flug=false;     button1->Text=L"実行";   } このように設定したボタンを何回も連続して押すと、この関数を実行中は多重実行されないことを想定しているのですが、やってみると多重実行されてしまいます。 どの様にすれば多重実行しないように出来るのでしょうか? また、この関数を実行中は自分で作成したアイテムを操作することが、一切できなくなってしまうのですが、何か解決方法は無いでしょうか? 宜しくお願いします。

  • ダイアログから画像ファイルは表示できますか。

    Microsoft Visual Basic 2005を使用しています。 いろいろやっているのですがどなたか教えていただけませんか。 Buttonをクリックするとダイアログが開いて画像ファイルを参照させて画像ファイルを選択してからフォルダパスをtextboxに書き込むことはできますか。 同時に PictureBoxに画像を表示もできるのでしょうか。 よろしくお願いします。 もし、ご不明な点がありましたらお伝えください。

  • javascript関数について

    <!DOCTYPE html> <html> <head> <title></title> <script type="text/javascript"> function extract() { var textbox = document.getElementById("barcode"); var amount = textbox.value.substr(22,3); textbox.value = amount; } </script> </head> <body> バーコード: <input type="text" id="barcode" size="64" value=""> <input type="button" value="部分取り出し" onclick="extract()"> </body> </html> 上記のソースコードでボタンを押せば22行目(先頭から数えて21番目までを削除?し22番目から25番目までを表示)するプログラムをかきましたが、ボタンを押さず表示したいのですが、どうすればいいですか?教えてください。 お願いいたします。

  • C# のクリックイベント

    別のイベントからクリックイベントを発生させるのに Button1.PerformClick(); は、うまくいくのですが、 これがピクチャーボックスになったとき pictureBox1.PerformClick(); 下記のエラーが出てしまいます。 ピクチャーボックスのボタンクリックイベントを発生させる方法はないでしょうか? 'System.Windows.Forms.PictureBox' に 'PerformClick' の定義が含まれておらず、型 'System.Windows.Forms.PictureBox' の最初の引数を受け付ける拡張メソッドが見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。

  • Actionscript 同じような処理をまとめたい

    閲覧ありがとうございます。 プログラム初心者です。 FlashでサイトのTOPページに置くメニューを作成しています。 Flashのヘルプを見ながらできたのですが5つあるボタンにつきいちいち関数を作っていて、もう少しコンパクトに書きたいと思いました。 きれいに書くにはどうするのがベストでしょうか? もしかしてActionscriptは一つのボタンにつき一つの関数を書かなければいけないのですか? //自分なりに書いてみてうまくいかなかったソースです。 //実行するとボタンを押す前に一番上に書いたアドレス(http://address1.php)に飛んでしまいました。 var Add1:String = "http://address1.php"; var Add2:String = "http://address2.php"; var Add3:String = "http://address3.php"; var Add4:String = "http://address4.php"; var Add5:String = "http://address5.php"; function onClickButton(event:MouseEvent, address:String) :void { var selectURL:URLRequest = new URLRequest(address); navigateToURL(selectURL,"_self"); } button1.addEventListener(MouseEvent.CLICK, onClickButton(Add1)); button2.addEventListener(MouseEvent.CLICK, onClickButton(Add2)); button3.addEventListener(MouseEvent.CLICK, onClickButton(Add3)); button4.addEventListener(MouseEvent.CLICK, onClickButton(Add4)); button5.addEventListener(MouseEvent.CLICK, onClickButton(Add5));

    • ベストアンサー
    • Flash
  • javascript 動的フォームの追加、削除について

    JAVASCRIPTを使って、追加ボタンを押したときに、入力フォーム(textbox)を2個、3個と追加させ、入力フォーム横に設置した削除ボタンで削除ボタン横の入力フォームを削除したいと思っております。 1)delInput2()の引数でボタンごとの情報(何番目のボタンか)を渡したい。 どのようなjavascriptを書けばよいか、ご教授願えませんでしょうか。 どうぞよろしくお願い致します。 <script type="text/javascript"> var arInput = 0; var Default = arInput; function addInput() { //追加処理 arInput ++ $("#area").append('<span id=\"group'+arInput+'\"><input type=\"text\" name=\"text'+arInput+'\" value=\"入力項目'+arInput+'\" /><input type=\"button\" onclick=\"delInput2()\" name=\"button'+arInput+'\" value=\"削除'+arInput+'\" /><br></span>\n'); } function delInput() { //削除処理 $("#group"+arInput).remove(); if(arInput > Default){ arInput -- } } function delInput2() { //指定項目削除処理 } </script> <form> <fieldset id="area"> <fieldset> <input type="button" onclick="addInput()" value="一行追加" /> <input type="button" onclick="delInput()" value="一行削除" /> </fieldset> </form>

  • コマンドボタンやテキストボックスの変数化(?)

    今、VB2005ExpressEditionでソフトを作っているのですが、 コマンドボタン(Button)を並べ、その隣にテキストボックス(Textbox)を並べ、 約80組のボタン・テキストの組を作りました。 そのボタンを隣に記載してある数字分だけクリックさせたいのですが、クリックさせる関数を public function clk(a1 as integer,a2 as integer) If a2 < 1 Then Exit Function Dim a3 As Integer = a2 Do If a1 = 1 Then Call Button1.PerformClick() If a1 = 2 Then Call Button2.PerformClick() ....... a3=a3-1 loop until a3<1 End function として、a1をクリックするボタンの添え字、a2=textbox(a1).text(a1の部分は毎回手打ち)としていますが、buttonやtextboxの名前を変数化して、読み込むことができれば、コードを省略できると思います。何かいいアイデアはないものでしょうか?

  • Ajaxで作成したinputタグが正しく動作しない

    元々htmlで作成してあるform内容をAjaxで送受信し、 その得られたjsonデータを元に新規にテーブルを作成しています。 ここまでは出来ているのですが、更にこのテーブルにそれぞれの項目にソートボタンを実装したいのですが、これが実現しません。 <input type="button"で作成したボタン(元のhtmlにあるボタンと同様の記述)は元ページのphpに遷移してしまい、 <button></button>で作成したボタンは何の動作も行いません。 元々ある検索ボタンと同様に非同期でpostするには 追加で作成したform内の要素はどのようにすれば可能でしょうか? //テーブル作成関数 function create_table(data){ //テーブルヘッダー var text = "<table><thead><tr><th>foo</th><th></th>"; $("li", "#foo_list").each(function(i, v){ text += "<th>" + v.innerHTML + "\      //●inputボタン作成部 <input type='button' class='search_btn' value='検索' />\ <button class='search_btn' value='" + v.id + "_up' ><img src='./foo.gif'></button>\ <button class='search_btn' value='" + v.id + "_down' ><img src='./bar.gif'></button></th>"; }); text += "</tr></thead><tbody>"; ~省略~ //テーブル閉じる text += "</tbody></table>"; $("#result_table").html(text); } //ajax送受信 $(function(){ var jsdata = ""; $('.search_btn').click(function(){ var form = $("#frm"); var json = $(form.serializeArray());   $.ajax({ url : "./hoge.php", type : "post", data : json, success: function (jsdata){ results_data = eval( "(" + jsdata + ")" ); create_table(results_data); } }); }); }); よろしくお願いいたします。

専門家に質問してみよう