Popup中ListBox的SelectChange事件关闭弹出窗体后主窗体点击无效BUG

WPF的BUG!
弹出框的 自定义控件里有Popup, Popup里面放一个ListBox

 在ListBox中的SelectionChange事件触发关闭弹出框后,主窗体存在一定概率卡死(但点击标题又能用的BUG)

 

步骤一: 新建个自定义WPF控件UserControl

Xaml代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<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>

逻辑代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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代码

1
2
3
4
5
6
7
8
9
10
11
12
13
public partial class DialogWin : Window
    {
        public DialogWin()
        {
            InitializeComponent();
            mySelect.EnterDown += (o1, e1) =>
            {
                //mySelect.IsDropDownOpen = false;              //不起作用
                //Dispatcher.InvokeAsync(Close);                //还是会卡顿
                this.Close();
            };           
        }
    }

  

步骤三,在主窗体弹出DialogWin

xaml代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<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();
        }
    }
复制代码

运行程序....

解决方案: 开启线程延迟关闭弹出体【最无语做法】

代码下载

posted @   老板娘的神秘商店  阅读(580)  评论(9编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示
主题色彩
不要让你喜欢的人在约会,而你却在加班