2016-06-20 3 views
-2

なぜ、私は新しいボタンを作成して参照しようとするとNullReferenceExceptionを取得する理由を説明できますか?ボタンの作成と名前の割り当ては正常に機能しますが、参照はできません。C#windowsフォームの参照コントロール - NullReferenceException

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; 

namespace DragNDrop_1 
{ 
public partial class Form1 : Form 
{ 
    //Variables---------------------------------------------------------------------- 
    int ButtonID = 100; 
    bool isDraggingButton = false; 
    public Form1() 
    { 
     InitializeComponent(); 
    } 
    //----------------------------------------------------------------------Variables 
    private void btn_addButton_Click(object sender, EventArgs e) 
    { 
     AddButton(); 
    } 

    public void AddButton() 
    { 
     Button b = new Button(); 
     b.Name = "Button" + ButtonID.ToString(); 
     b.Text = "Button" + ButtonID.ToString(); 
     b.Location = new Point(ButtonID, ButtonID); 
     ButtonID = ButtonID + 100; 
     pnl_DragNDrop.Controls.Add(b); 
     isDraggingButton = true; 
    } 

    private void DragTimer_Tick(object sender, EventArgs e) 
    { 
     if (isDraggingButton == true) 
     { 
      Point mouse = PointToClient(MousePosition); 
      this.Controls["Button" + ButtonID.ToString()].Location = new Point(mouse.X + 20, mouse.Y + 20); 

     } 
    } 

} 
} 

例外は、作成された最後のボタンを参照しようとするタイマーで発生します。私はこの例外に関していくつかのスレッドを読んでいますが、まだエラーを見つけることはできません。 はい、私はこれが非常に乱雑であることを知っており、カスタムループを作成するか、タイマーを解除/再有効化する必要がありますが、これはテスト目的のためだけです。私はC#とWindows Formsを初めて使用していることに注意してください。

編集:Lukasz Mによって説明されているように、これは所有権に関する問題です(用語が正しくない可能性があります。私が思い付く最高のドイツ語 - 英語翻訳です)。これは、私が「重複した」スレッドからの質問の焦点でもなく、回答にも言及されていません。それでも私の英語力には疑問があります。とにかく、私は本当にスレッドを読んでいるが、解決策を見つけることができなかったことを明確にしたかっただけです。たぶん英語とC#のスキルが不足しているだけかもしれませんが、これは重複していないと確信しています。

+1

[NullReferenceExceptionとは何か、それを修正するにはどうすればいいですか?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix -it) –

答えて

4

AddButtonメソッドの場合ボタンを作成しますが、フォームのコントロールに直接追加するのではなく、pnl_DragNDrop.Controlsコレクションに追加します。

あなたはこの変更を試みることができます。これに

this.Controls["Button" + ButtonID.ToString()].Location = new Point(mouse.X + 20, mouse.Y + 20); 

pnl_DragNDrop.Controls["Button" + ButtonID.ToString()].Location = new Point(mouse.X + 20, mouse.Y + 20); 

をし、それが正常に動作する必要があります。

もう1つの方法は、メソッド内の変数ではなく、クラスフィールドにbボタンを保存することです。このようにして、ControlsコレクションのIdで検索することなく、別の方法でコントロールを参照することができます。 Idの値が異なる複数のボタンを追加することもできます。そのため、実際に作成されたボタンを保存および参照するための実装は、実際のユースケースによって異なる場合があります。コードを作るために

更新

実際にも、あなたはbコントロールを作成した後、あなたは、その名前を構成するために使用する変数を変更することを何卒ご了承下さい、仕事:

ButtonID = ButtonID + 100; 

その後、DragTimer_Tickにメソッド変更された値を使用してコントロールの名前を再構築しますが、既に異なるので、コントロールが見つかりません。

コントロールを名前で検索する場合、前の値ButtonIDを保存するか、後でコントロールを見つけるためにボタン名(コメントに記載されている)を使用して文字列全体を保存することができます。

+0

不幸にも(そして意外なことに)これはうまくいかなかったが、私はあなたのポイントを得る。しかし、問題を理解し、新しい変数(文字列)を作成してb.Nameを渡すことで解決しました。 –

+0

'b'コントロールを作成した後で、' ButtonID'変数( 'ButtonID')を変更するので、うまくいきませんでした。その後、コントロールを再度検索しようとすると、変更された値が使用されます。 –

関連する問題