欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-02 09:19:53
WPF的BUG!弹出框的 自定义控件里有Popup, Popup里面放一个ListBox 在ListBox中的SelectionChange事件触发关闭弹出框后,主窗体存在一定概率卡死(但点击标题又能用的BUG) 步骤一: 新建个自定义WPF控件UserControl Xaml代码:

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) =>
            {
                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) =>
            {
                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();
        }
    }

运行程序....

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

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

代码下载