c# - 当弹出窗口中的数据网格捕获鼠标时,wpf 弹出窗口不会自动关闭

标签 c# wpf popup grid mousecapture

我有一个带有 StaysOpen=False 的弹出窗口,所以我想通过单击弹出窗口之外的任意位置来关闭它。在弹出窗口中,我有一个 DataGrid。如果我打开弹出窗口然后单击其他地方,弹出窗口将关闭。但如果在弹出窗口外单击之前我将单击 DataGrid 中的列标题,则不会发生这种情况。测试 XAML:

<Window x:Class="Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black">
<Grid>
    <ToggleButton x:Name="btn" VerticalAlignment="Top">Open</ToggleButton>
    <Popup StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=btn}" > 
        <DataGrid Width="150" Height="150">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Column" />
            </DataGrid.Columns>
        </DataGrid>
    </Popup>
</Grid>
</Window>

我认为这是因为列标题在单击时捕获鼠标并且弹出窗口不再接收鼠标事件。我试图在 LostMouseCapture 事件上添加一个处理程序,以便通过弹出窗口捕获鼠标,但它似乎并不那么容易工作。有什么想法吗?

最佳答案

也许它会有所帮助。 附加行为:

public class DataGridColumnHeaderReleaseMouseCaptureBehavior {
    public static DataGrid GetReleaseDGCHeaderBehavior(DependencyObject obj) {
        return (DataGrid)obj.GetValue(ReleaseDGCHeaderBehaviorProperty);
    }

    public static void SetReleaseDGCHeaderBehavior(DependencyObject obj, Boolean value) {
        obj.SetValue(ReleaseDGCHeaderBehaviorProperty, value);
    }

    public static readonly DependencyProperty ReleaseDGCHeaderBehaviorProperty =
        DependencyProperty.RegisterAttached("ReleaseDGCHeaderBehavior",
            typeof(DataGrid),
            typeof(DataGridColumnHeaderReleaseMouseCaptureBehavior),
            new UIPropertyMetadata(default(DataGrid), OnReleaseDGCHeaderBehaviorPropertyChanged));

    private static Popup _popup;

    private static void OnReleaseDGCHeaderBehaviorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        var oldGrid = (DataGrid)e.OldValue;
        if (oldGrid != null)
            oldGrid.MouseLeave -= OnMouseLeave;
        var refSender = d as Popup;
        _popup = refSender;
        if (refSender != null) {
            var refGrid = e.NewValue as DataGrid;
            if (refGrid != null) {
                refGrid.MouseLeave += OnMouseLeave;
            }
        }
    }
    static void OnMouseLeave(object sender, MouseEventArgs args) {
        if (_popup != null)
            typeof(Popup).GetMethod("EstablishPopupCapture", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(_popup, null);
    }
}

XAML:

<Popup x:Name="popup"
bhvrs:DataGridColumnHeaderReleaseMouseCaptureBehavior.ReleaseDGCHeaderBehavior="{Binding ElementName=dataGrid}">
  <DataGrid x:Name="dataGrid"/>
</Popup>

关于c# - 当弹出窗口中的数据网格捕获鼠标时,wpf 弹出窗口不会自动关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5807734/

相关文章:

C# 将 Excel 图表作为对象(而不是图片)导出到 Word

c# - 混合 WPF 和 winforms 项目 DPI 意识

c# - WPF 使用 Magstrip 编码打印到打印机

html - 用 CSS 动画弹出书本效果

C#——侵入式树结构,使用CRTP

c# - C++ 中的变量变量名

c# - 如何使用修剪功能修剪列表内部

c# - WPF TreeView - 选择和扩展节点

php - 如何在调整窗口大小时调整 YouTube 播放器的大小

java - JComboBox 确定项目是否在下拉列表中可见