Popup中ListBox的SelectChange事件关闭弹出窗体后主窗体点击无效BUG
WPF的BUG!
弹出框的 自定义控件里有Popup, Popup里面放一个ListBox
在ListBox中的SelectionChange事件触发关闭弹出框后,主窗体存在一定概率卡死(但点击标题又能用的BUG)
步骤一: 新建个自定义WPF控件UserControl
Xaml代码:
<UserControl x:Class="WpfApplication1.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" d:DesignHeight="30" d:DesignWidth="200"> <Grid> <Grid x:Name="PART_Container"> <DockPanel Margin="0,0,1,0"> <ToggleButton x:Name="PART_ToggBtn" DockPanel.Dock="Right" BorderThickness="1" BorderBrush="#959595" Margin="-1,0,0,0" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:UserControl1}}"> > </ToggleButton> <TextBox x:Name="txtAutoComplete" /> </DockPanel> </Grid> <Popup x:Name="PART_Popup" Opacity="0" Width="{Binding ElementName=PART_Container,Path=ActualWidth}" IsOpen="{Binding Path=IsDropDownOpen,Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:UserControl1}}" PopupAnimation="Slide" Placement="Bottom" StaysOpen="False" AllowsTransparency="True" PlacementTarget="{Binding ElementName=txtAutoComplete}" VerticalOffset="0" MinHeight="50" MaxHeight="300"> <ListBox x:Name="listboxSuggestion" BorderBrush="Transparent" BorderThickness="0"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Item1}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Popup> </Grid> </UserControl>
逻辑代码:
public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); List<Tuple<string, string, string>> tupes = new List<Tuple<string, string, string>>(); Enumerable.Range(1, 10).Select(p => p.ToString().PadLeft(3, '0')).ToList().ForEach(p => tupes.Add(new Tuple<string, string, string>(p, p, p))); listboxSuggestion.ItemsSource = tupes; listboxSuggestion.SelectionChanged += (o1, e1) => { //this.IsDropDownOpen = false; //不能解决问题 RoutedEventArgs args = new RoutedEventArgs(EnterDownEvent, o1); //选中项改变触发 this.RaiseEvent(args); }; } #region 回车触发事件 //声明和注册路由事件 public static readonly RoutedEvent EnterDownEvent = EventManager.RegisterRoutedEvent( "EnterDown", RoutingStrategy.Bubble, typeof(EventHandler<RoutedEventArgs>), typeof(UserControl1)); //CLR事件包装 public event RoutedEventHandler EnterDown { add { this.AddHandler(EnterDownEvent, value); } remove { this.RemoveHandler(EnterDownEvent, value); } } #endregion #region 是否打开下拉框 public bool IsDropDownOpen { get { return (bool)GetValue(IsDropDownOpenProperty); } set { SetValue(IsDropDownOpenProperty, value); } } public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(UserControl1), new PropertyMetadata(false)); #endregion }
步骤二: 新建个Window窗体DialogWin
xaml代码
<Window x:Class="WpfApplication1.DialogWin" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="DialogWin" Height="88.846" Width="210"> <Grid> <local:UserControl1 Width="120" Height="22" x:Name="mySelect" /> </Grid> </Window>
cs代码
public partial class DialogWin : Window { public DialogWin() { InitializeComponent(); mySelect.EnterDown += (o1, e1) => { //mySelect.IsDropDownOpen = false; //不起作用 //Dispatcher.InvokeAsync(Close); //还是会卡顿 this.Close(); }; } }
步骤三,在主窗体弹出DialogWin
xaml代码
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="44,32,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> <TextBox HorizontalAlignment="Left" Height="23" Margin="198,32,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> <TextBox HorizontalAlignment="Left" Height="23" Margin="350,32,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> <Button x:Name="button" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="44,82,0,0"/> <Button x:Name="button1" Content="弹出对话框" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="156,82,0,0" Click="button1_Click"/> </Grid> </Window>
cs代码
/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { var s = new DialogWin(); s.Owner = this; s.WindowStartupLocation = WindowStartupLocation.CenterOwner; s.ShowDialog(); } }
运行程序....
解决方案: 开启线程延迟关闭弹出体【最无语做法】
转载保留源出处即可,商业使用请自行鉴别,使用本博客中公开内容做任何违法犯罪于本作者无关