Search code examples
c#.netwpferror-handlingcontrols

Assigning event GotFocus to all TextBoxes in WPF-Application


I wanted to add GotFocus-Event to every Textbox in my WPF-Aplication, because its for Touch Devices and everytime a TextBox is in use the OSK should open. I got Problems with procedure adding the Event to my TextBoxes. The Aplication is already build for pc (I'm in an interhsip and my goal is it to bring this Apl. to Windows 8 Touch Devices).This is the link, where I got my Inspiration from: Add/Remove handler to textbox

and here is my Solution:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    foreach (Control tb in this.Controls)
    {
        if (tb is TextBox)
        {
            TextBox tb1 = (TextBox)tb;
            tb1.GotFocus += TextBox_GotFocus;
        }
    }
}

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    KeyBoardManager.LaunchOnScreenKeyboard();
}

when I want to run this Code I have the following Error:

Error 1 'OSK_Test.MainWindow' does not contain a definition for 'Controls' and no extension method 'Controls' accepting a first argument of type 'OSK_Test.MainWindow' could be found (are you missing a using directive or an assembly reference?)

What have I got to do, that it works? And of course it's the same with LostFocus!


Solution

  • The problem as I see it is that you are using an answer meant for a Winforms application with a Wpf application, in the Winforms your controls can be added to the main form, therefore this.Controls works, in Wpf your MainWindow has a Content Property which can contain only one item, usually a Grid, Canvas or Panel of some kind. This object is where your TextBox's are located.

    Note: this will work only if your TextBox's are children of the MainWindows LayoutControl and not Embedded any deeper if it is embedded deeper you will need to name the Panel that they are contained in and iterate through that, also I am not suggesting that this is the proper way to approach your problem, just trying to point out what your problem is:

    private void Grid_Loaded(object sender, RoutedEventArgs e)
    {
        foreach (Control tb in ((Panel)this.Content).Children)
        {
            if (tb is TextBox)
            {
                TextBox tb1 = (TextBox)tb;
                tb1.GotFocus += TextBox_GotFocus;
                tb1.LostFocus += tb1_LostFocus;
            }
    
        }
    
    }
    

    Based on OP's comment:

    You will need to give your StackPpanel a name or use an existing one if one exists. i.e.

    <StackPanel x:Name="MyStackPanel" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100">
        <TextBox Height="23" TextWrapping="Wrap" Text="TextBox"/>
        <TextBox Height="23" TextWrapping="Wrap" Text="TextBox"/>
        <TextBox Height="23" TextWrapping="Wrap" Text="TextBox"/>
        <TextBox Height="23" TextWrapping="Wrap" Text="TextBox"/>
        <TextBox Height="23" TextWrapping="Wrap" Text="TextBox"/>
    </StackPanel>
    

    Usuage would be something like this:

     public MainWindow()
    {
        InitializeComponent();
    
        foreach (Control tb in MyStackPanel.Children)
        {
            if (tb is TextBox)
            {
                TextBox tb1 = (TextBox)tb;
                tb1.GotFocus += TextBox_GotFocus;
                tb1.LostFocus += tb1_LostFocus;
            }
        }
    }