WPF, wie erstelle ich eine Textbox dynamisch und das Textfeld auf eine Schaltfläche klicken finden?

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

Frage

Ich schaffe eine TextBox und ein Button dynamisch mit dem folgenden Code:

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

ich zu einem Click-Ereignisse auf die Click Me Taste anschließen. Die mir klicken sogar richtig gebrannt. Allerdings kann ich nicht finden, die TextBox ich dynamisch eingegeben werden.

Hier ist mein click me Ereignis:

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

Wie kann ich die TextBox txtNumber finden?

War es hilfreich?

Lösung

Josh G hatte den Hinweis, der diesen Code festgelegt:. Verwendung Registername ()

Drei Vorteile hier:

  1. Verwendet nicht eine Membervariable den Verweis auf die dynamisch erstellte TextBox zu speichern.
  2. Kompiliert.
  3. Komplette Code.

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

Andere Tipps

Eine andere Methode ist die zugehörige TextBox als Button Tag zu setzen, wenn sie Instanziierung.

btnClickMe.Tag = txtNumber;

So können Sie es zurück in Ereignishandler abrufen können.

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

Sie können Ihre ursprünglichen Click-Handler an der Arbeit, indem Sie den Namen des Textfeldes Registrierung:

someStackPanel.RegisterName(txtNumber.Name, txtNumber);

Dies wird dann können Sie Findname auf dem Stackpanel und finden Sie das TextBox nennen.

Wenn Sie eine umfassende Suche über die visuelle Struktur der Kontrollen tun möchten, können Sie die VisualTreeHelper Klasse.

Verwenden Sie den folgenden Code durch alle visuellen Kinder einer Kontrolle iterieren:

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

    if (child is TextBox)
        // Do something
}

Wenn Sie in den Baum suchen, nach unten wollen, sollten Sie diese Schleife rekursiv durchzuführen, etwa so:

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

Gibt es eine Möglichkeit Sie das Textfeld ein Feld steuern in Ihrer Klasse in Ihrem Generator-Methode anstelle einer Variablen machen

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);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top