【发布时间】:2011-03-21 21:34:43
【问题描述】:
当下拉列表并将鼠标悬停在下拉列表中的某个项目上时,该项目将突出显示,但除非单击该项目,否则文本框中显示的选定值不会更改。我正在寻找一种方法来修改从 ComboBox 继承的控件中的鼠标悬停行为。我尝试过覆盖 OnMouseEnter 和 OnMouseMove 等函数。
【问题讨论】:
标签: wpf .net-3.5 wpf-controls
当下拉列表并将鼠标悬停在下拉列表中的某个项目上时,该项目将突出显示,但除非单击该项目,否则文本框中显示的选定值不会更改。我正在寻找一种方法来修改从 ComboBox 继承的控件中的鼠标悬停行为。我尝试过覆盖 OnMouseEnter 和 OnMouseMove 等函数。
【问题讨论】:
标签: wpf .net-3.5 wpf-controls
改为使用 TextBlock、带箭头的 ToggleButton 和 ListBox 创建您自己的控件。选中 ToggleButton 时显示列表框。当用户将鼠标悬停在列表框项上时,更改文本框中的文本并更新选定项的某些属性或触发事件。
【讨论】:
您可以通过覆盖 OnMouseMove 来实现。 MouseEventArgs 的OriginalSource 属性将为您提供鼠标正下方的元素。您可以使用 ContainerFromElement 获取包含该元素的 ComboBoxItem,然后使用 ItemContainerGenerator.ItemFromContainer 获取要选择的项目:
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
var container = ContainerFromElement((DependencyObject)e.OriginalSource);
if (container != null)
{
SelectedItem = ItemContainerGenerator.ItemFromContainer(container);
}
}
【讨论】:
这就是我在代码中解决相同问题的方法,希望它对其他人有用,或者只是迈向完整 xaml 解决方案的一步。
我遵循了 Quartermeister 的解决方案。但在我看来,需要子类化 ComboBox 是一个设计弱点(因为这样做只是为了处理 MouseOver 事件)。因为我只需要 MouseOver 事件的不同行为,所以我只在附加到 XAML 文件的类中实现了处理 MouseOver 事件的方法。
首先,我使用了EventSetter 类,它是Setter 类的子类,它专门用于Events。所以EventSetter可以用来装饰FrameworkElements,就像我们通常用Setter做的一样。
<ComboBox>
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<EventSetter Event="MouseMove" Handler="_updateModel"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
这样,当鼠标悬停时,每个 ComboBoxItem 都会调用 _updateModel。
我的 _updateModel 实现非常简单,它强烈基于 Quartermeister 的工作:
private void _updateModel(object sender, MouseEventArgs e)
{
DependencyObject src = e.Source as DependencyObject;
ComboBoxItem cbi = VisualTreeHelper.GetParent(src) as ComboBoxItem;
while ((cbi == null) && (src!=null))
{
src = VisualTreeHelper.GetParent(src);
cbi = src as ComboBoxItem;
}
if (cbi != null)
{
ComboBox cb = ItemsControl.ItemsControlFromItemContainer(cbi) as ComboBox;
if (cb != null)
{
var container = cb.ContainerFromElement((DependencyObject)e.OriginalSource);
if (container != null)
{
cb.SelectedItem = cb.ItemContainerGenerator.ItemFromContainer(container);
}
}
}
}
解决相同问题的其他方法可以使用blend's behaviors 由于不值得在这里解释的原因,我无法使用这种行为。
【讨论】: