none
How to clear all textBoxes in one function? RRS feed

  • Question

  • Hi all,

    I have more Grids (for example: 15-20) so I know only this way how to clear/enable all textBoxes ... and other type (chckBox, radioButton, ...)

    pubic void clearAll(bool b)
    {
        // for dataGrid1
        foreach (var txt in LogicalTreeHelper.GetChildren(dataGrid1).OfType<TextBox>())
        { txt.IsReadOnly = b; }
    
        // for dataGrid2
        foreach (var txt in LogicalTreeHelper.GetChildren(dataGrid2).OfType<TextBox>())
        { txt.IsReadOnly = b; }
    
        // ....
    }

    But is there a way how to do it in one function, one three, or one ... ?

    Thank you.




    Tuesday, October 22, 2019 11:45 AM

All replies

  • Hello,

    From what you have asked it's unclear what you are working with e.g. text box elements in a WPF grid or something else (I mentioned WPF because in your history it appears there are many post on WPF).

    If WPF we can move your question to that forum.

    Either way, no matter what type of project this is, condensing functionality is not always wise, instead if the follow code you posted works I see nothing wrong with this especially if something goes wrong in the future it's easy to diagnose. Always consider a section of code that works but want to optimize rather than make it flexible go with optimized and works rather than make it condensed to work against to controls.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, October 22, 2019 12:05 PM
  • Hi,

    at first thank you for answer. I think my question is more than clear. In my program, for example in MainWindow, I have more Grids <Grid /> That code I mentioned is above is to clear/enable all textBoxes in certain grid. If I have more Grids I need more that funcions. My question was to do it in one foreach, one function ...

    maybe not just to clear dataGrids "children" datagrid->textBoxes but "children->children" stackpanel->datagrid->textboxes

    like this ... stackPanel->dataGrid1(..2,3,4,5, ....)->textBoxes

    foreach (var txt in LogicalTreeHelper.GetChildren(stackPanel1).OfType<TextBox>())
        { txt.IsReadOnly = b; }

    Tuesday, October 22, 2019 12:17 PM
  • There is a WPF forum you can post to.

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=wpf

    Tuesday, October 22, 2019 12:23 PM
  • Maybe something like this (totally untested and off the top of my head, there may be typos or syntax issues):

    public void ClearTextBoxes<T>(T control)
    {
        foreach (var txt in LogicalTreeHelper.GetChildren(control).OfType<TextBox>())
            { txt.IsReadOnly = b; }
    }
    
    

    And call it like this:

    ClearTextBoxes(stackPanel1);


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Tuesday, October 22, 2019 3:21 PM
  • Okay let's look at using a method to get a specific type of control in a container such as TextBox controls in a StackPanel then call this with (in this case one of two) a language extension method.

    Add this class to your project

    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using static System.Windows.Media.VisualTreeHelper;
    
    namespace WpfApp1
    {
        public static class WindowHelpers
        {
            /// <summary>
            /// Clear TextBox controls in a container
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="control"></param>
            public static void ClearTextBoxes<T>(this DependencyObject control)
            {
                foreach (var textBox in FindChildren<TextBox>(control))
                {
                    textBox.Text = "";
                }
            }
            /// <summary>
            /// Enable or disable a TextBox in a container
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="control"></param>
            /// <param name="enable"></param>
            public static void EnableTextBoxes<T>(this DependencyObject control, bool enable = false)
            {
                foreach (var textBox in FindChildren<TextBox>(control))
                {
                    textBox.IsReadOnly = enable;
                }
            }
    
            public static IEnumerable<T> FindChildren<T>(DependencyObject dependencyItem) where T : DependencyObject
            {
                if (dependencyItem != null)
                {
                    for (var index = 0; index < GetChildrenCount(dependencyItem); index++)
                    {
                        var child = GetChild(dependencyItem, index);
                        if (child is T dependencyObject)
                        {
                            yield return dependencyObject;
                        }
    
                        foreach (var childOfChild in FindChildren<T>(child))
                        {
                            yield return childOfChild;
                        }
                    }
                }
            }
        }
    }

    Make all TextBox controls in StackPanel1 read only

    StackPanel1.EnableTextBoxes<StackPanel>(true);

    Reverse, make them editable

    StackPanel1.EnableTextBoxes<StackPanel>();

    Clear all TextBox controls in StackPanel2

    StackPanel2.ClearTextBoxes<StackPanel>();

    Clear all TextBox controls in all StackPanel controls on a window.

    FindChildren<StackPanel>(this).ToList()
        .ForEach(sp => sp.ClearTextBoxes<StackPanel>());

    Complete window code

    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using static WpfApp1.WindowHelpers;
    
    namespace WpfApp1
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
            /// <summary>
            /// Disable all TextBox controls in StackPanel1
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                StackPanel1.EnableTextBoxes<StackPanel>(true);
            }
            /// <summary>
            /// Clear all TextBox controls in StackPanel2
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                StackPanel2.ClearTextBoxes<StackPanel>();
            }
    
            private void Button_Click_2(object sender, RoutedEventArgs e)
            {
                FindChildren<StackPanel>(this).ToList()
                    .ForEach(sp => sp.ClearTextBoxes<StackPanel>());
            }
        }
    }

    Notes

    * Bonnie sparked this idea

    * FindChildren is not mine, it came from a post on StackOverflow.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange


    Tuesday, October 22, 2019 6:08 PM
  • If you do not need Binding for your textboxes, then you can add something like this:

       <TextBox Text="{Binding Content, ElementName=label1, Mode=OneWay}" . . ./>

    where label1 is an invisible (collapsed) label.

    Then executing label1.Content = null; label1.Content = "" will clear all of bound textboxes.

    Can be done for IsEnabled property as well.

    Wednesday, October 23, 2019 5:32 AM