2009-10-20 81 views
1

这里是发生了什么:防止ListBox聚焦,但保留ListBoxItem(s)可聚焦

我有一个列表框项目。列表框有重点。某些项目(例如第5个)被选中(具有蓝色背景),但没有“边框”。

当我按'向下'键时,焦点从列表框移动到第一个ListBoxItem。
(我想要的是使第6项选择,无论'边框')

当我使用'标签'导航,列表框再也没有收到焦点。

但是,当收集被清空并再次填充时,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; 

其中fsItemsObservableCollection<OuterItem>

我描述的可用性问题发生时,我Clear()收集(fsItems)并填写新的项目。

+0

虚拟化可能是一个问题 – 2009-10-21 12:41:07

回答

1

请提供您的代码。通常这个问题的原因在于ContentPresenters和KeyboardNavigation.IsTabStop属性。但有时候并非如此。所以代码会有所帮助。

+0

是的,请提供一个片段和所需结果的描述,这是很难解密的问题.... – 2009-10-23 18:21:51

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