Despite some posts on this forum and others i cannot find something that tells me how to set the focus on a TextBox
.
I have a userControl with many labels and textBoxes. When the form is开发者_C百科 loaded I want the a particular textBox to have the focus.
I have set the tabIndex but that didn't seem to work.
Any suggestions?
You can use the FocusManager.FocusedElement
attached property for this purpose. Here's a piece of code that set the focus to TxtB by default.
<StackPanel Orientation="Vertical" FocusManager.FocusedElement="{Binding ElementName=TxtB}">
<TextBox x:Name="TxtA" Text="A" />
<TextBox x:Name="TxtB" Text="B" />
</StackPanel>
You can also use TxtB.Focus()
in your code-behind if you don't want to do this in XAML.
You can apply this property directly on the TextBox :
<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
I am new to using WPF and reading through the above examples I had a similar experience trying set the focus to a textbox using the xaml code examples given, i.e. all the examples above didn't work.
What I found was I had to place the FocusManager.FocusElement in the page element. I assume this would probably work as well if you used a Window as the parent element. Anyway, here is the code that worked for me.
<Page x:Class="NameOfYourClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Title="Title"
Height="720"
Width="915"
Background="white"
Loaded="pgLoaded"
FocusManager.FocusedElement="{Binding ElementName=NameOfYourTextBox}">
<!-- Create child elements here. -->
</Page>
I have a TextBox inside a Grid inside a DataTemplate which I want to have keyboard focus when it becomes visible. I also found that
<DataTemplate x:Key="DistanceView" DataType="{x:Type vm:ROI}">
<Grid FocusManager.FocusedElement="{Binding ElementName=tbDistance}">
<TextBox x:Name="tbDistance" Grid.Column="1" Grid.Row="1" VerticalAlignment="Bottom"/>
</Grid>
</DataTemplate>
did not work for me.
However when I call Focus() in the parent ContentControl
private void ContentControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((sender as ContentControl).IsVisible)
{
(sender as ContentControl).Focus();
}
}
it starts to work and the caret is visible in the TextBox. I think the FocusScope has to be given focus for the FocusManager.FocusedElement property to have any effect.
Jerry
From experimenting around, the xaml solution
FocusManager.FocusedElement="{Binding ElementName=yourElement}"
seems to work best when you place it in the highest element in the window hierarchy (usually Window, or the Grid you place everything else in)
Usage:
local:FocusManager.FocusOnLoad="True"
public class FocusManager
{
public static readonly DependencyProperty FocusOnLoad = DependencyProperty.RegisterAttached(
"FocusOnLoad",
typeof(bool),
typeof(FocusManager),
new UIPropertyMetadata(false, new PropertyChangedCallback(OnValueChanged))
);
private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (!(sender is Control control))
return;
if ((bool) e.NewValue == false)
return;
control.Loaded += (s, e) => control.Focus();
}
public static bool GetFocusOnLoad(DependencyObject d) => (bool) d.GetValue(FocusOnLoad);
public static void SetFocusOnLoad(DependencyObject d, bool value) => d.SetValue(FocusOnLoad, value);
}
FocusManager was not in intellisense and this confused me a bit. I just typed the entire attribute and it worked.
FocusManager.FocusedElement="{Binding ElementName=MyTextBox}"
Microsoft Visual Studio Enterprise 2015 version 14.0.23107.0/C#/WPF
For completeness, there is also a way to handle this from code behind (e.g. in the case of controls that, for whatever reason, are created dynamically and don't exist in XAML). Attach a handler to the window's Loaded event and then use the ".Focus()" method of the control you want. Bare-bones example below.
public class MyWindow
{
private VisualCollection controls;
private TextBox textBox;
// constructor
public MyWindow()
{
controls = new VisualCollection(this);
textBox = new TextBox();
controls.Add(textBox);
Loaded += window_Loaded;
}
private void window_Loaded(object sender, RoutedEventArgs e)
{
textBox.Focus();
}
}
bind the element you want to point the focus in as
FocusManager.FocusedElement= "{Binding ElementName= Comobox1}"
in grid or groupbox etc
Further to my comment on Feb 04 '22, I solved it this way:
In the UserControl definitionin the XAML add a Loaded event handler. (pressing tab after Loaded= will automatically add an event handler to the code behind)
Then edit the event handler in the code behind:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
expressionTextBox.Focus();
}
I'm hoping that WPF is clever enough to handle th unhooking of the evnt at some point, allowing the class to be garbage collected and not give rise to memory leaks, but I don't know. I'd be interested in any comments on that.
精彩评论