15


5

WPFテキストボックスを動的に作成してボタンクリックでテキストボックスを見つける方法を教えてください。

私は以下のコードを使って TextBox`と Button`を動的に作成しています。

Button btnClickMe = new Button();
btnClickMe.Content = "Click Me";
btnClickMe.Name = "btnClickMe";
btnClickMe.Click += new RoutedEventHandler(this.CallMeClick);

someStackPanel.Childern.Add(btnClickMe);

TextBox txtNumber = new TextBox();
txtNumber.Name = "txtNumber";
txtNumber.Text = "1776";

someStackPanel.Childern.Add(txtNumber);

Clickイベントを `Click Me`ボタンにつなげます。 私をクリックしても正しく発射されます。 しかし、私が動的に入力した `TextBox`が見つかりません。

これが私のクリックミーイベントです。

protected void ClickMeClick(object sender, RoutedEventArgs e)
{
    // Find the phone number
    TextBox txtNumber = this.someStackPanel.FindName("txtNumber") as TextBox;

    if (txtNumber != null)
    {
        string message = string.Format("The number is {0}", txtNumber.Text);

        MessageBox.Show(message);
    }
    else
    {
        MessageBox.Show("Textbox is null");
    }
}

TextBox`や txtNumber`を見つけるにはどうすればいいですか?

5 Answer


15


Josh Gはこのコードを修正した手がかりを得ました:RegisterName()を使用してください。

ここに3つの利点があります。

  1. 動的に作成されたTextBoxへの参照を保存するためにメンバー変数を使用しません。

  2. コンパイルします。

  3. 完全なコード

システムを使用する。 System.Windowsを使用します。 System.Windows.Controlsを使用します。

名前空間AddControlsDynamically {public部分クラスWindow1:Window {public void Window_Loaded(object sender、RoutedEventArgs e){GenerateControls(); public void GenerateControls(){Button btnClickMe = new Button();} btnClickMe.Content = "クリックしてください"; btnClickMe.Name = "btnClickMe"; btnClickMe.Click = new RoutedEventHandler(this.CallMeClick); someStackPanel.Children.Add(btnClickMe); TextBox txtNumber = new TextBox(); txtNumber.Name = "txtNumber"; txtNumber.Text = "1776"; someStackPanel.Children.Add(txtNumber); someStackPanel.RegisterName(txtNumber.Name、txtNumber); CallMeClick(オブジェクトの送信側、RoutedEventArgs e){TextBox txtNumber =(TextBox)this.someStackPanel.FindName( "txtNumber");} string message = string.Format( "番号は{0}"、txtNumber.Text); MessageBox.Show(メッセージ)。 }}}


5


別の方法はそれらをインスタンス化するとき関連する TextBox`を Button Tag`として設定することです。

btnClickMe.Tag = txtNumber;

この方法であなたはそれをイベントハンドラで取り戻すことができます。

protected void ClickMeClick(object sender, RoutedEventArgs e)
{
    Button btnClickMe = sender as Button;
    if (btnClickMe != null)
    {
        TextBox txtNumber = btnClickMe.Tag as TextBox;
        // ...
    }
}


4


テキストボックスの名前を登録すると、元のクリックハンドラを機能させることができます。

someStackPanel.RegisterName(txtNumber.Name、txtNumber);

これにより、StackPanelでFindNameを呼び出してTextBoxを見つけることができます。


3


コントロールのビジュアルツリーを介して包括的な検索をしたい場合は、VisualTreeHelperクラスを使用できます。

次のコードを使用して、コントロールのすべての視覚的な子を反復処理します。

for(int i = 0; i <VisualTreeHelper.GetChildrenCount(parentObj); i){DependencyObject child = VisualTreeHelper.GetChild(parent、i);

if(childはTextBox)//何かをする}

もしあなたがツリーを捜し出したいのなら、このループを再帰的に実行したいでしょう。

パブリックデリゲートvoid TextBoxOperation(TextBox box);

public bool SearchChildren(DependencyObject parent、TextBoxOperation op){(int i = 0; i <VisualTreeHelper.GetChildrenCount(parent); i){DependencyObject child = VisualTreeHelper.GetChild(parent、i);

TextBox box = TextBoxとしての子。

if(box!= null){op.Invoke(box); trueを返します。 }

bool found = SearchChildren(child、op);

(見つかった)trueを返した場合}}


2


あなたがあなたのジェネレータメソッドの中の変数の代わりにあなたのクラスの中のTextBoxコントロールフィールドを作ることができる方法はありますか

パブリッククラスMyWindow:Window {private TextBox txtNumber;}

public void Window_Loaded(){GenerateControls(); }

public void GenerateControls(){Button btnClickMe = new Button(); btnClickMe.Content = "クリックしてください"; btnClickMe.Name = "btnClickMe"; btnClickMe.Click = new RoutedEventHandler(this.CallMeClick); someStackPanel.Childern.Add(btnClickMe); txtNumber = new TextBox(); txtNumber.Name = "txtNumber"; txtNumber.Text = "1776"; someStackPanel.Childern.Add(txtNumber); }

protected void ClickMeClick(object sender、RoutedEventArgs e){//電話番号を検索します文字列message = string.Format( "番号は{0}"、txtNumber.Text); MessageBox.Show(メッセージ)。 }}