2009-02-11 43 views
13

tôi đang tạo ra một TextBoxButton động bằng cách sử dụng đoạn mã sau:WPF làm cách nào để tạo một hộp văn bản động và tìm hộp văn bản trên một nút bấm?

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); 

tôi treo lên đến một sự kiện click vào nút Click Me. Nút bấm tôi thậm chí được kích hoạt chính xác. Tuy nhiên tôi không thể tìm thấy số TextBox Tôi đã nhập động.

Sau đây là tôi bấm cho tôi sự kiện:

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"); 
    } 
} 

Làm thế nào tôi có thể tìm thấy TextBoxtxtNumber?

+0

ý của bạn là this.someStackPanel.FindName ("txtNumber")? – foson

+0

Cảm ơn tôi đã sửa nó. Nó vẫn không hoạt động. –

+0

Rất nhiều lỗi chính tả trong này: (1) s/childern/Trẻ em/ (2) Nút được chuyển đến CallMeClick nhưng mã cho thấy ClickMeClick (3) Nút được đặt vào someStackPanel nhưng sau đó tìm kiếm trong pnlCallMe Rõ ràng, điều này không phải là mã bạn đang chạy. – hughdbrown

Trả lời

14

Josh G có đầu mối cố định mã này: sử dụng RegisterName().

Ba lợi ích ở đây:

  1. Không sử dụng một biến thành viên để lưu các tài liệu tham khảo cho TextBox động tạo ra.
  2. Biên dịch.
  3. Toàn bộ mã.

    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); 
         } 
        } 
    } 
    
+0

Điều này hoạt động khá tốt. Tôi thay đổi điều này thành câu trả lời được chấp nhận bởi vì nó làm những gì tôi muốn ban đầu. Các công trình khác cũng tốt, nhưng tôi không muốn tạo ra hộp văn bản và lưu trữ chúng. –

2

Có cách nào bạn có thể làm cho các TextBox điều khiển một lĩnh vực trong lớp học của bạn thay vì một biến bên trong phương pháp phát điện của bạn

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); 
    } 
} 
+0

Điều này sẽ hoạt động. Tuy nhiên không có cách nào để tìm thấy nó? Điều gì xảy ra nếu tôi có 10 hộp văn bản? Là giải pháp để tạo Danh sách và chỉ sử dụng LINQ để tìm chúng? –

+0

Tôi chấp nhận câu trả lời này bởi vì nó hoạt động và nếu tôi có 10 hộp văn bản, tôi có thể tạo danh sách và tìm chúng trong danh sách. Cảm ơn. –

+0

Mã không biên dịch: Childern, CallMeClick không được xác định, vv – hughdbrown

5

phương pháp khác là để thiết lập liên quan đến TextBox như Button Tag khi instanciating họ.

btnClickMe.Tag = txtNumber; 

Bằng cách này bạn có thể truy xuất lại trong trình xử lý sự kiện.

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

Điều này cũng hoạt động. –

3

Nếu bạn muốn thực hiện tìm kiếm toàn diện thông qua cây điều khiển trực quan, bạn có thể sử dụng lớp VisualTreeHelper.

Sử dụng đoạn mã sau để lặp qua tất cả các trẻ em hình ảnh của một điều khiển:

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

    if (child is TextBox) 
     // Do something 
} 

Nếu bạn muốn tìm kiếm xuống cây, bạn sẽ muốn thực hiện vòng lặp này đệ quy, như vậy:

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; 
    } 
} 
4

Bạn có thể nhận handler nhấp chuột ban đầu của bạn để làm việc bằng cách đăng ký tên của hộp văn bản:

someStackPanel.RegisterName(txtNumber.Name, txtNumber); 

này sau đó sẽ cho phép bạn gọi FindName trên StackPanel và tìm ra TextBox .

Các vấn đề liên quan