WPF 텍스트 상자를 동적으로 만들고 버튼 클릭에서 텍스트 상자를 찾으려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/537073

문제

나는 만들고있다 TextBox 그리고 a 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 Me 단추. 클릭 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?

도움이 되었습니까?

해결책

Josh G는이 코드를 수정 한 단서가있었습니다. RegisterName () 사용하십시오.

여기에 세 가지 이점 :

  1. 동적으로 만든 텍스트 상자에 대한 참조를 저장하기 위해 멤버 변수를 사용하지 않습니다.
  2. 컴파일.
  3. 완전한 코드.

    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace AddControlsDynamically
    {
        public partial class Window1 : Window
        {
            public void Window_Loaded(object sender, RoutedEventArgs e)
            {
                GenerateControls();
            }
            public void GenerateControls()
            {
                Button btnClickMe = new Button();
                btnClickMe.Content = "Click Me";
                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);
            }
            protected void CallMeClick(object sender, RoutedEventArgs e)
            {
                TextBox txtNumber = (TextBox) this.someStackPanel.FindName("txtNumber");
                string message = string.Format("The number is {0}", txtNumber.Text);
                MessageBox.Show(message);
            }
        }
    }
    

다른 팁

또 다른 방법은 연관성을 설정하는 것입니다 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;
        // ...
    }
}

텍스트 상자의 이름을 등록하여 원래 클릭 핸들러가 작동하도록 할 수 있습니다.

someStackPanel.RegisterName(txtNumber.Name, txtNumber);

그러면 StackPanel에서 FindName을 호출하고 TextBox를 찾을 수 있습니다.

Visual Tree of Controls를 통해 포괄적 인 검색을하려면 VisualTreeHelper 클래스를 사용할 수 있습니다.

다음 코드를 사용하여 컨트롤의 모든 시각적 어린이를 반복하십시오.

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

    if (child is TextBox)
        // Do something
}

트리를 검색하려면이 루프를 재귀 적으로 수행하고 싶을 것입니다.

public delegate void TextBoxOperation(TextBox box);

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

        TextBox box = child as TextBox;

        if (box != null)
        {
            op.Invoke(box);
            return true;
        }

        bool found = SearchChildren(child, op);

        if (found)
            return true;
    }
}

텍스트 상자 제어를 발전기 메소드 내부의 변수 대신 클래스에서 필드로 만들 수있는 방법이 있습니까?

public class MyWindow : Window
{
    private TextBox txtNumber;

    public void Window_Loaded()
    {
        GenerateControls();
    }

    public void GenerateControls()
    {
        Button btnClickMe = new Button();
        btnClickMe.Content = "Click Me";
        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)
    {    
        // Find the phone number    
        string message = string.Format("The number is {0}", txtNumber.Text);        
        MessageBox.Show(message);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top