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

运行程序....

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

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

代码下载

上一篇:Asp.net点击按钮弹出文件夹选择框的实现(网页)


下一篇:lucene+IKAnalyzer实现中文纯文本检索系统