tags:

views:

312

answers:

2

Here is what happens:

I have a listbox with items. Listbox has focus. Some item (say, 5th) is selected (has a blue background), but has no 'border'.

When I press 'Down' key, the focus moves from ListBox to the first ListBoxItem.
(What I want is to make 6th item selected, regardless of the 'border')

When I navigate using 'Tab', the Listbox never receives the focus again.

But when the collection is emptied and filled again, ListBox itself gets focus, pressing 'Down' moves the focus to the item.

How to prevent ListBox from gaining focus?

P.S.
listBox1.SelectedItem is my own class, I don't know how to make ListBoxItem out of it to .Focus() it.

EDIT: the code

Xaml:

<UserControl.Resources>
    <me:BooleanToVisibilityConverter x:Key="visibilityConverter"/>
    <me:BooleanToItalicsConverter x:Key="italicsConverter"/>
</UserControl.Resources>
<ListBox x:Name="lbItems">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <ProgressBar HorizontalAlignment="Stretch" 
                             VerticalAlignment="Bottom"
                             Visibility="{Binding Path=ShowProgress, Converter={StaticResource visibilityConverter}}"
                             Maximum="1"
                             Margin="4,0,0,0"
                             Value="{Binding Progress}"
                             />
                <TextBlock Text="{Binding Path=VisualName}" 
                           FontStyle="{Binding Path=IsFinished, Converter={StaticResource italicsConverter}}"
                           Margin="4"
                           />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <me:OuterItem Name="Regular Folder" IsFinished="True" Exists="True" IsFolder="True"/>
    <me:OuterItem Name="Regular Item" IsFinished="True" Exists="True"/>
    <me:OuterItem Name="Yet to be created" IsFinished="False" Exists="False"/>
    <me:OuterItem Name="Just created" IsFinished="False" Exists="True"/>
    <me:OuterItem Name="In progress" IsFinished="False" Exists="True" Progress="0.7"/>
</ListBox>

where OuterItem is:

public class OuterItem : IOuterItem
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public bool IsFolder { get; set; }

    public bool IsFinished { get; set; }
    public bool Exists { get; set; }
    public double Progress { get; set; }

    ///  Code below is of lesser importance, but anyway 
    ///
    #region Visualization helper properties
    public bool ShowProgress
    {
        get
        {
            return !IsFinished && Exists;
        }
    }
    public string VisualName
    {
        get
        {
            return IsFolder ? "[ " + Name + " ]" : Name;
        }
    }
    #endregion

    public override string ToString()
    {
        if (IsFinished)
            return Name;

        if (!Exists)
            return "  ???  " + Name;

        return Progress.ToString("0.000 ") + Name;
    }

    public static OuterItem Get(IOuterItem item)
    {
        return new OuterItem()
        {
            Id = item.Id,
            Name = item.Name,
            IsFolder = item.IsFolder,

            IsFinished = item.IsFinished,
            Exists = item.Exists,
            Progress = item.Progress
        };
    }
}

Сonverters are:

/// Are of lesser importance too (for understanding), but will be useful if you copy-paste to get it working
public class BooleanToItalicsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool normal = (bool)value;
        return normal ? FontStyles.Normal : FontStyles.Italic;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool exists = (bool)value;
        return exists ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

But most important, is that UserControl.Loaded() has:

lbItems.Items.Clear();
lbItems.ItemsSource = fsItems;

where fsItems is ObservableCollection<OuterItem>.

The usability problem I describe takes place when I Clear() that collection (fsItems) and fill with new items.

+1  A: 

Please provide your code. Usually the cause of this problem lies in ContentPresenters and KeyboardNavigation.IsTabStop property. But sometimes it's not. So the code would help.

Anvaka
Yes, please provide a snippet and the description of the desired outcome, it is hard to de-cipher the question....
Sergey Aldoukhov
A: 

The answer to your question may depend on the way your listbox is getting focus. Here is the solution if you are using an access key (ex: alt+c). You have to implement your own listbox control and override the OnAccessKey method. If this is not your scenario, then I would suggest looking into the OnIsKeyboardFocusWithinChanged method. Try using the same approach I did in the code below.

protected override void OnAccessKey(System.Windows.Input.AccessKeyEventArgs e)
    {
        if (SelectedIndex >= 0)
        {
            UIElement element = ItemContainerGenerator.ContainerFromIndex(SelectedIndex) as UIElement;
            if (element != null)
            {
                element.Focus();
            }
        }           
    }
Alex