How to focus a datatemplated TextBox in the first

2019-05-04 17:14发布

When the user clicks a button in the application, a window opens up. I want the TextBox belonging to the first item in the ItemsControl to be focused, so that the user can start typing as soon as the Window is opened, without needing to manually select the TextBox.

How can this be done?

For simplicity, we can say that the Window looks approximately like this:

<Window>
    <Grid>
        <ItemsControl ItemsSource="{Binding MyItems}">
            <DataTemplate>
                <Grid>
                    <StackPanel>
                        <StackPanel>
                            <customControls:ValidationControl>
                                <TextBox Text="" />
                            </customControls:ValidationControl>
                        </StackPanel>
                    </StackPanel>
                </Grid>
            </DataTemplate>
        </ItemsControl>
    </Grid>
</Window>

UPDATE After looking at propsed answers as well and this link: Window Loaded and WPF The modified solution is as follows:

<Window>
    <Grid>
        <ItemsControl x:Name="myItemsControl" ItemsSource="{Binding MyItems}">
            <DataTemplate>
                <Grid>
                    <StackPanel>
                        <StackPanel>
                            <customControls:ValidationControl>
                                <TextBox Text="" />
                            </customControls:ValidationControl>
                        </StackPanel>
                    </StackPanel>
                </Grid>
            </DataTemplate>
        </ItemsControl>
    </Grid>
</Window>

In constructor:

this.Loaded += new RoutedEventHandler(ThisWindowLoaded);

Loaded Method:

private void ThisWindowLoaded(object sender, RoutedEventArgs e)
{
    var textbox = FindVisualChild<TextBox>(myItemsControl.ItemContainerGenerator.ContainerFromIndex(0));
    FocusManager.SetFocusedElement(myItemsControl, textbox);
}

Super-duper method:

public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
            if (child != null && child is T)
            {
                return (T)child;
            }

            T childItem = FindVisualChild<T>(child);
            if (childItem != null)
                return childItem;
        }
    }
    return null;
}

2条回答
闹够了就滚
2楼-- · 2019-05-04 17:33

If is WPF you should do smt like below :

<Grid>
        <DataGridCell>
            <Grid>
                <TextBox x:Name="TextBox1" Text=" ">

                    </TextBox>
            </Grid>
        </DataGridCell>

</Grid>

And code-behind:

 TextBox1.Focus();
查看更多
疯言疯语
3楼-- · 2019-05-04 17:52

FocusManager.SetFocusedElement() may be what you are finding.

Xaml

   <ItemsControl x:Name="ItemsControl">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBox />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl> 

In Loaded event, you focus on first textbox:

   var textbox = ItemsControl.ItemContainerGenerator.ContainerFromIndex(0).FindChildByType<TextBox>();
   FocusManager.SetFocusedElement(ItemsControl, textbox);

Following is the way I find first child:

  public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null
                    && child is T)
                {
                    return (T)child;
                }

                T childItem = FindVisualChild<T>(child);
                if (childItem != null)
                    return childItem;
            }
        }
        return null;
    }
查看更多
登录 后发表回答