fanarek
fanarek

Reputation: 367

Can't set focus on first item of ListBox

I can't set focus on first item of my ListBox. ListBox has some collection bound. It looks like, that first everything in code-behind doing its stuff then there is control initializing so I would have always -1 as SelectedIndex.

XAML

<Window x:Class="Labels.Szablony"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Labels"
    mc:Ignorable="d"
    Title="Labels" Height="350" Width="250" WindowStartupLocation="CenterScreen"
    ResizeMode="CanMinimize" KeyDown="Window_KeyDown" Background="#FFF6A300" >
<Window.DataContext>
    <local:LabelGridViewModel/>
</Window.DataContext>
<ScrollViewer VerticalScrollBarVisibility="Hidden" VerticalContentAlignment="Center"
              VerticalAlignment="Center" Background="#FFF6A300">
    <Grid Background="#FFF6A300" Name="labelGrid">
        <ListBox x:Name="SzablonyBox" ItemsSource="{Binding LabelsCollection, IsAsync=True}"
              HorizontalAlignment="Center" VerticalAlignment="Top"
             MinWidth="100" MinHeight="100" BorderBrush="{x:Null}"
             Background="{x:Null}" TextSearch.Text="BLABLAB"
             TextSearch.TextPath="Name" IsTextSearchEnabled="True"
                 VerticalContentAlignment="Center" Margin="0 25 0 0"
                 Width="250" HorizontalContentAlignment="Center">
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <EventSetter Event="PreviewKeyDown"
                                 Handler="ListBoxItem_PreviewKeyDown"/>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <DockPanel Width="214">
                        <TextBlock Text="{Binding Name}"
                               FontSize="12" Height="35"
                               VerticalAlignment="Center"
                               HorizontalAlignment="Center"
                               Width="250" 
                               TextAlignment="Center"/>
                    </DockPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <TextBox x:Name="InputText"
                 Text="{Binding Path=Filter, UpdateSourceTrigger=PropertyChanged}"
                 HorizontalAlignment="Center" Height="22" TextWrapping="Wrap"
                 VerticalAlignment="Top" Width="250" Background="#FFF6A300"
                 IsEnabled="False" BorderBrush="#FFF6A300"
                 VerticalContentAlignment="Center"
                 HorizontalContentAlignment="Center" 
                 Foreground="Black" SelectionBrush="{x:Null}"/>
    </Grid>
</ScrollViewer>

What i'm trying to do looks like:

public Labels()
{
    InitializeComponent();

    LabelsBox.Focus();
    LabelsBox.SelectedIndex = 0;

    var item = LabelsBox.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem;

    item.Focus();
}

Of course there is an exception, because item is null. Like I said SelectedIndex is always -1. What am I doing wrong ?

Upvotes: 0

Views: 1126

Answers (1)

Clemens
Clemens

Reputation: 128147

The ItemsSource Binding is asynchronous, so there are certainly not yet any items available while the constructor is running.

Change the Binding to be synchronous, i.e. the default behavior:

<ListBox ItemsSource="{Binding LabelsCollection}" ...>

You may also execute your initialization code as late as possible, by moving it to a Loaded event handler:

public Labels()
{
    InitializeComponent();
    ...

    Loaded += (s, e) =>
    {
        var item = (ListBoxItem)LabelsBox.ItemContainerGenerator.ContainerFromIndex(0);
        item?.Focus();
    };
}

Upvotes: 2

Related Questions