jack - developer of stuff

Hi, I need to have a listbox that has 2 datatemplates on it, one for rowselected and one for row.

I need the behaviour to: allow the user to scroll up or down with the arrow keys. When a row is selected, by mouse or keyboard, one of the text boxes in the selected template, would get focus and they can start typeing. when the user uses the arrow keys, they go back to scrolling in the listbox.

I'm hoping there is a fairly "elegant/generic" way of doing this without a lot of codebehind'ing so it can be reused across a large application.

Thanks!

here is what i have so far:

resources/templates and listbox.

Code Block


<DataTemplate x:Key="row">
<StackPanel Orientation="Horizontal" Name="spItem">
<Button Name="btn" Focusable="false" Content="{Binding labelText}" Width="100" />
<TextBox Name="txt" Focusable="false" Text ="{Binding Text}" Width="100" />
<TextBox Name="Q" Text ="{Binding Quantity }" Width="100" />
</StackPanel>
</DataTemplate>

<DataTemplate x:Key="rowSelected">
<StackPanel Orientation="Horizontal" Name="spItem">
<Button Focusable="false" Name="btnsel" Width="100" Content="{Binding labelText}"/>
<TextBox Focusable="false" Name="txtsel" Width="100" Text ="{Binding Text}" Background="Orange" />
<TextBox Focusable="true" Name="Qsel" Width="100" Text ="{Binding Quantity }"/>
</StackPanel>
</DataTemplate>

<Style x:Key="listTemplate" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource row}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="true" >
<Setter Property="ContentTemplate" Value="{StaticResource rowSelected}" />
</Trigger>
</Style.Triggers>
</Style>

<ListBox ListBoxItem.Selected="ListBox_Selected" KeyboardNavigation.DirectionalNavigation="Cycle" IsSynchronizedWithCurrentItem="True" ItemContainerStyle="{StaticResource listTemplate}" ItemsSource="{Binding}" Name="listBox1">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>



Re: Windows Presentation Foundation (WPF) Setting focus on a texbox inside a datatemplate of Listbox

Zhou Yong

I am enable to focus on the selected ListBoxItem when user press return key in the editing textbox, and then you can start navigating between ListBoxItems using standard up and down array keys. tell me if this behaviour fits into your need.

Code Block

<ListBox TextBox.KeyDown="KeyDownEventHandler"/>

private void KeyDownEventHandler(Object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
UIElement focusedElement = Keyboard.FocusedElement as UIElement;
if (focusedElement != null)
{
focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
}
e.Handled = true;
}
}

Hope it helps






Re: Windows Presentation Foundation (WPF) Setting focus on a texbox inside a datatemplate of Listbox

jack - developer of stuff

It is very close, now i just need the part about, "When a row is selected, by mouse or keyboard, one of the text boxes in the selected template, would get focus and they can start typeing." - , Any help appreciated, thanks.




Re: Windows Presentation Foundation (WPF) Setting focus on a texbox inside a datatemplate of Listbox

Zhou Yong

After several times of try, I finally get those things sorted out, just hook up to the ListBox.SelectionChanged event, and do something as follows:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)

{

ListBoxItem item = listBox1.ItemContainerGenerator.ContainerFromIndex(listBox1.SelectedIndex) as ListBoxItem;

if (item != null && Keyboard.PrimaryDevice.ActiveSource != null)

{

this.Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(delegate

{

KeyEventArgs args = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Tab);

args.RoutedEvent = Keyboard.KeyDownEvent;

InputManager.Current.ProcessInput(args);

}));

}

}

This looks like a hack, and I think there might be other better solutions from other community members. if you just want to have someting to work, you can try the piece of code above.