Reputation: 45106
When the user selects a value from the ListBox I want tbEntry to receive focus.
The tbEntry.Focus(); in the SelectedPastEntry set does nothing.
(tbEntry is populated with the value from the ListBox).
The tbEntry.Focus(); in the Button_Click does work.
How to have tbEntry entry receive focus after a selection from ListView?
<TextBox Grid.Row="1" x:Name="tbEntry" Text="{Binding Path=Entry, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" AcceptsReturn="True"/>
<ListBox x:Name="lbPast" Grid.Row="2" ItemsSource="{Binding Path=PastEntries}" ScrollViewer.VerticalScrollBarVisibility="Visible"
SelectedItem="{Binding Path=SelectedPastEntry, Mode=TwoWay}"/>
<Button Grid.Row="3" Click="Button_Click" Content="focus"/>
public string SelectedPastEntry
{
get { return selectedPastEntry; }
set
{
selectedPastEntry = null;
entry = value;
NotifyPropertyChanged("SelectedPastEntry");
NotifyPropertyChanged("Entry");
tbEntry.Focus();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
tbEntry.Focus();
}
Below works better
For some reason the lbPast.SelectedIndex = -1; makes the focus work some times
The first time an item is selected in lbPast the focus goes to tbEntry
The problem is if the same item is selected again then the lbPast item receives focus
The problem with a select of the same item is that set is not fired
But on the first click I see the get on SelectedPastEntry called and null returned
So don't know why set is not called on the second select of the same item
public string SelectedPastEntry
{
get { return selectedPastEntry; }
set
{
if (selectedPastEntry == value || (string.Compare(selectedPastEntry, entry, true) == 0))
{
selectedPastEntry = null;
lbPast.SelectedIndex = -1;
NotifyPropertyChanged("SelectedPastEntry");
tbEntry.Focus();
}
//selectedPastEntry = value;
selectedPastEntry = null;
lbPast.SelectedIndex = -1;
NotifyPropertyChanged("SelectedPastEntry");
entry = value;
NotifyPropertyChanged("Entry");
tbEntry.Focus();
}
}
This was the fix
I know you are going to doubt this but selectedPastEntry was set to null and saw the get called (by lbPast)
But that did NOT change the value of lbPast.SelectedValue
private void lbPastSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Debug.WriteLine(SelectedPastEntry); // this is null
Debug.WriteLine(lbPast.SelectedValue); // this is not null
if (lbPast.SelectedIndex != -1)
lbPast.SelectedIndex = -1;
if (lbPast.SelectedValue != null)
lbPast.SelectedValue = null;
tbEntry.Focus();
}
Upvotes: 1
Views: 1047
Reputation: 22702
Setter of property are not the best place to set the Focus to the Control
. Instead of try SelectionChanged
event of ListView
:
Occurs when the selection of a Selector changes.
Example:
XAML
<ListView SelectionChanged="ListView_SelectionChanged" />
Code-behind
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
tbEntry.Focus();
}
Or you can do this: create a handler for the PropertyChanged
event and check what kind of property has been updated:
public MyViewModel()
{
MyModel = new MyModel();
MyModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(MyModel_PropertyChanged);
}
private void MyModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName.Equals("SelectedPastEntry"))
{
System.Diagnostics.Debug.WriteLine("SelectedPastEntry changed");
}
}
Upvotes: 1
Reputation: 1002
Set theActiveControl property of the form and you should be fine
this.ActiveControl = tbEntry;
Upvotes: 0