WPF 自定义ComboBox
需求:
ComboBox下拉列表,在光标移出ComboBox后,下拉列表立即收起。
利用WPF的 自定义控件 继承于ComboBox开发项目中需要的JComboBox,其代码如下:
namespace FrameWPF { /// <summary> /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。 /// /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。 /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 /// 元素中: /// /// xmlns:MyNamespace="clr-namespace:FrameWPF" /// /// /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。 /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 /// 元素中: /// /// xmlns:MyNamespace="clr-namespace:FrameWPF;assembly=FrameWPF" /// /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用, /// 并重新生成以避免编译错误: /// /// 在解决方案资源管理器中右击目标项目,然后依次单击 /// “添加引用”->“项目”->[浏览查找并选择此项目] /// /// /// 步骤 2) /// 继续操作并在 XAML 文件中使用控件。 /// /// <MyNamespace:JComboBox/> /// /// </summary> public class JComboBox : ComboBox { static JComboBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(JComboBox), new FrameworkPropertyMetadata(typeof(JComboBox))); } public JComboBox() { this.Loaded += JComboBox_Loaded; } private void JComboBox_Loaded(object sender, RoutedEventArgs e) { Popup popup = (Popup)this.Template.FindName("PART_Popup", this); if (popup != null)//JComboBox刚加载时Popup并未显示,故不能找到 { popup.MouseLeave += Popup_MouseLeave; popup.MouseEnter += Popup_MouseEnter; timer = new System.Timers.Timer { Interval = 1000 //此处时间最好能过配置文件设置,以便根据实际情况修改 }; timer.Elapsed += Timer_Elapsed; this.DropDownOpened += JComboBox_DropDownOpened; } } private void JComboBox_DropDownOpened(object sender, EventArgs e) { timer?.Start(); } System.Timers.Timer timer; private void Popup_MouseEnter(object sender, MouseEventArgs e)//由于定时器1S后会关闭Popup,若点开Popup 在1S内进入了Popup,则定时器停止。 { timer.Stop(); } private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { timer.Stop(); Application.Current.Dispatcher.Invoke(() => { this.IsDropDownOpen = false; }); } private void Popup_MouseLeave(object sender, MouseEventArgs e) { this.IsDropDownOpen = false; } } }
代码中添加了一个定时器,是为了避免若点开了下拉列表的Popup,但一直停在原处或移到了非Popup的地方,则1S后就关闭Popup。
如此可在触摸环境下,点开了combobox的下拉列表,避免了不做选择,就点击其他按钮时无响应的情况(因为你在点击时会先去收起ComboBox的Popup,再次点击才会响应按钮的事件; 非按钮,若是文本框,则需要双击才能选中文本框,然后才能录入文本)。
*****有道无术,术尚可求;有术无道,止于术。*****