WPF 텍스트 상자를 동적으로 만들고 버튼 클릭에서 텍스트 상자를 찾으려면 어떻게해야합니까?
-
22-08-2019 - |
문제
나는 만들고있다 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 () 사용하십시오.
여기에 세 가지 이점 :
- 동적으로 만든 텍스트 상자에 대한 참조를 저장하기 위해 멤버 변수를 사용하지 않습니다.
- 컴파일.
완전한 코드.
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);
}
}
제휴하지 않습니다 StackOverflow