2009-10-20 6 views
1

Вот что происходит:Предотвращение блокировки ListBox, но оставить объект ListBoxItem (s) focusable

У меня есть список с элементами. В списке есть фокус. Выбран какой-то элемент (например, 5-й) (имеет синий фон), но не имеет границы.

Когда я нажимаю клавишу «Вниз», фокус перемещается из списка ListBox в первый элемент ListBoxItem.
(Я хочу, чтобы выбранный 6-й элемент был независимо от «границы»)

Когда я перемещаюсь с помощью «Tab», Listbox никогда не получает фокус снова.

Но когда коллекция очищается и заполняется снова, сам ListBox получает фокус, нажатие «Вниз» перемещает фокус на элемент.

Как предотвратить перехват ListBox?

P.S.
listBox1.SelectedItem - это мой собственный класс, я не знаю, как сделать ListBoxItem из него .Focus().

EDIT: код

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> 

где OuterItem является:

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 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(); 
    } 
} 

Но самое главное, что UserControl.Loaded() имеет:

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

где fsItems является ObservableCollection<OuterItem>.

Проблема юзабилити, которую я описываю, имеет место, когда я Clear(), что коллекция (fsItems) и заполните ее новыми элементами.

+0

виртуализация может быть проблема –

ответ

1

Просьба представить ваш код. Обычно причиной этой проблемы является свойство ContentPresenters и KeyboardNavigation.IsTabStop. Но иногда это не так. Таким образом, код поможет.

+0

Да, пожалуйста, предоставьте фрагмент и описание желаемого результата, это вопрос трудно, чтобы ДЭ-шифра .... –

0

Ответ на ваш вопрос может зависеть от того, как ваш список получает фокус. Вот решение, если вы используете ключ доступа (например: alt + c). Вы должны реализовать свой собственный элемент управления списком и переопределить метод OnAccessKey. Если это не ваш сценарий, я бы предложил изучить метод OnIsKeyboardFocusWithinChanged. Попробуйте использовать тот же подход, который я сделал в приведенном ниже коде.

protected override void OnAccessKey(System.Windows.Input.AccessKeyEventArgs e) 
    { 
     if (SelectedIndex >= 0) 
     { 
      UIElement element = ItemContainerGenerator.ContainerFromIndex(SelectedIndex) as UIElement; 
      if (element != null) 
      { 
       element.Focus(); 
      } 
     }   
    } 
Смежные вопросы