在Silverlight中,当您向上或向下按箭头或标签时,当前HIGHLIGHTED(未选中)项目周围会绘制一个小方框。我想找出小方框所在的项目,以便在用户按Tab键时将其设为所选项目。我花了三天时间,也许其他人可以使用它。
void SelectorRapidAccessKeyBehavior_DropDownOpened(object sender, EventArgs e)
{
FindPopup();
}
private void FindPopup()
{
CleanUpPopupHandler();
pop = GetPopup(base.AssociatedObject);
if (pop != null && pop.Child != null)
{
pop.Child.KeyDown += AssociatedObject_KeyUp;
foreach (FrameworkElement c in Finder.FindVisualChildren<FrameworkElement>(pop.Child))
{
c.KeyDown += new KeyEventHandler(c_KeyDown);
}
}
}
void c_KeyDown(object sender, KeyEventArgs e)
{
int t = this.AssociatedObject.TabIndex;
Border ci = sender as Border;
if (e.Key == Key.Tab)
{
if (ci != null)
{
//this here is the magic line
var v = Finder.FindVisualChildren<FrameworkElement>((DependencyObject)pop.Child).Where(a => a.Opacity > 0 && a.Name == "FocusVisualElement" && a.Visibility == Visibility.Visible);//&& )
object o = v.First().DataContext;
int i = this.AssociatedObject.Items.IndexOf(o);
if (i > -1)
this.AssociatedObject.SelectedIndex = i;
pop.IsOpen = false;
DependencyObject d = Finder.FindParent<FloatableWindow>(this.AssociatedObject);
if (d == null)
d = Finder.FindParent<Window>(this.AssociatedObject);
Control c = Finder.FindVisualChildren<Control>(d).Where(a => a.TabIndex > t).OrderBy(a => a.TabIndex).FirstOrDefault();
if (c == null)
c = Finder.FindVisualChildren<Control>(d).OrderBy(a => a.TabIndex).FirstOrDefault();
if (c != null)
c.Focus();
}
}
}
答案 0 :(得分:1)
只需将KeyDown事件添加到项目中(可能说起来容易做起来难之)并选择项目,如果Key为Tab,则事件将针对焦点(具有围绕它的框)的事件触发,例如
<ComboBox Loaded="ComboBox_Loaded">
<ComboBoxItem>1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>3</ComboBoxItem>
<ComboBoxItem>4</ComboBoxItem>
<ComboBoxItem>5</ComboBoxItem>
</ComboBox>
private void ComboBoxItem_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab)
{
var cbi = sender as ComboBoxItem;
var cb = cbi.Parent as ComboBox;
cb.SelectedItem = cbi;
e.Handled = true;
cb.IsDropDownOpen = false;
}
}
private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
var cb = sender as ComboBox;
foreach (var item in cb.Items)
{
(item as ComboBoxItem).KeyDown += ComboBoxItem_KeyDown;
}
}
在WPF中我会知道一些更简洁的方法来附加事件,也许你可以想到一些事情。
答案 1 :(得分:0)
void SelectorRapidAccessKeyBehavior_DropDownOpened(object sender, EventArgs e)
{
FindPopup();
}
private void FindPopup()
{
CleanUpPopupHandler();
pop = GetPopup(base.AssociatedObject);
if (pop != null && pop.Child != null)
{
pop.Child.KeyDown += AssociatedObject_KeyUp;
foreach (FrameworkElement c in Finder.FindVisualChildren<FrameworkElement>(pop.Child))
{
c.KeyDown += new KeyEventHandler(c_KeyDown);
}
}
}
void c_KeyDown(object sender, KeyEventArgs e)
{
int t = this.AssociatedObject.TabIndex;
Border ci = sender as Border;
if (e.Key == Key.Tab)
{
if (ci != null)
{
//this here is the magic line
var v = Finder.FindVisualChildren<FrameworkElement>((DependencyObject)pop.Child).Where(a => a.Opacity > 0 && a.Name == "FocusVisualElement" && a.Visibility == Visibility.Visible);//&& )
object o = v.First().DataContext;
int i = this.AssociatedObject.Items.IndexOf(o);
if (i > -1)
this.AssociatedObject.SelectedIndex = i;
pop.IsOpen = false;
DependencyObject d = Finder.FindParent<FloatableWindow>(this.AssociatedObject);
if (d == null)
d = Finder.FindParent<Window>(this.AssociatedObject);
Control c = Finder.FindVisualChildren<Control>(d).Where(a => a.TabIndex > t).OrderBy(a => a.TabIndex).FirstOrDefault();
if (c == null)
c = Finder.FindVisualChildren<Control>(d).OrderBy(a => a.TabIndex).FirstOrDefault();
if (c != null)
c.Focus();
}
}
}