WPF كيف يمكنني إنشاء مربع نص ديناميكيا وابحث عن مربع النص على زر انقر؟

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

سؤال

أنا أخلق 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?

هل كانت مفيدة؟

المحلول

كان Josh G أدنى فكرة تم إصلاح هذا الرمز: استخدم اسم التسجيل ().

ثلاثة فوائد هنا:

  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 عند instusing لهم.

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

سيتيح لك ذلك بعد ذلك استدعاء FindName على StackPanel والعثور على مربع النص.

إذا كنت ترغب في إجراء بحث شامل من خلال شجرة عناصر التحكم المرئية، فيمكنك استخدام فئة 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