zoukankan      html  css  js  c++  java
  • 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();
            }
        }

    运行程序....

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

    代码下载

  • 相关阅读:
    强化学习 | D3QN原理及代码实现
    Airtest入门及多设备管理总结
    JS图片base64压缩
    ABP框架
    .net gof23种设计模式
    VS2013添加Socket
    VS2013用InstallShield打包winfrom项目
    .net core3.1 log4net无法写日志
    git commit 修改提交说明信息
    screen 使用总结
  • 原文地址:https://www.cnblogs.com/wandia/p/12703620.html
Copyright © 2011-2022 走看看