简体   繁体   English

WinForms 中的 WPF ElementHost 未收到鼠标点击

[英]WPF ElementHost in WinForms not receiving mouse clicks

I have a winforms application that I'd like to add a WPF user control to.我有一个 winforms 应用程序,我想向其中添加一个 WPF 用户控件。 The issue is when I run the program the WPF user control does not respond to mouse events.问题是当我运行程序时,WPF 用户控件不响应鼠标事件。 I can tab through the control and use the keyboard just fine, but the control does not respond to mouse clicks (the buttons don't even recognize when you hover over them).我可以浏览控件并很好地使用键盘,但控件不响应鼠标点击(当您将鼠标悬停在按钮上时甚至无法识别)。 I have attempted the solution in this SO question but it did not help: WPF WinForms Interop issue with Enable / Disable .我已经在这个 SO 问题中尝试了解决方案,但它没有帮助: WPF WinForms Interop issue with Enable / Disable Please see the code below.请看下面的代码。

User Control XAML用户控制 XAML

<UserControl x:Class="WinformsWPF.ucNotes"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="460" Background="#FFD7DFEC" IsHitTestVisible="False" Loaded="Window_Loaded">

    <UserControl.Resources>
        <LinearGradientBrush x:Key="DataGridHeaderBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="#b3dbcc" Offset="0" />
            <GradientStop Color="#61a99b" Offset="1" />
        </LinearGradientBrush>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot">
        <Label Content="Notes" HorizontalAlignment="Left" Margin="8,8,0,0" VerticalAlignment="Top" FontSize="16" FontWeight="Bold"/>
        <DataGrid x:Name="dgNotes" Margin="8,50,8,0" VerticalAlignment="Top" Height="121.28" d:LayoutOverrides="HorizontalAlignment" Background="#FFE4EEF3" AutoGenerateColumns="False" HorizontalGridLinesBrush="{x:Null}" VerticalGridLinesBrush="{x:Null}" ColumnWidth="Auto" CanUserDeleteRows="False" CanUserAddRows="False" CanUserReorderColumns="False" CanUserResizeRows="False" IsReadOnly="True" SelectionMode="Single" SelectionChanged="dgNotes_SelectionChanged" RowHeaderWidth="0" BorderBrush="{x:Null}" SelectedIndex="0">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="nDate" Header="Date"/>
                <DataGridTextColumn x:Name="nEmployee" Header="Employee"/>
                <DataGridTextColumn x:Name="nText" Header="Note" Width="*"/>
            </DataGrid.Columns>
            <DataGrid.Resources>
                <Style TargetType="{x:Type DataGridColumnHeader}">
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                    <Setter Property="Padding" Value="6" />
                    <Setter Property="BorderBrush" Value="#489283" />
                    <Setter Property="BorderThickness" Value="1" />
                    <Setter Property="Background" Value="{StaticResource DataGridHeaderBackgroundBrush}" />
                </Style>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="Background" Value="Transparent" />
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="#66D7DFEC" />
                        </Trigger>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="#DDD7DFEC" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
                <Style TargetType="{x:Type DataGridCell}">
                    <Setter Property="BorderThickness" Value="0" />
                    <Setter Property="Margin" Value="3" />
                    <Setter Property="Padding" Value="3" />
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="Transparent" />
                            <Setter Property="Foreground" Value="Black" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Resources>
        </DataGrid>
        <Grid Margin="8,175.28,8,8" >
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" MinHeight="25.96"/>
                <RowDefinition Height="Auto" MinHeight="25.96"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" MinWidth="61.757"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Label Content="Date" d:LayoutOverrides="Height" HorizontalAlignment="Left"/>
            <Label Content="Employee" Grid.Row="1" d:LayoutOverrides="Width"/>
            <Label Content="Notes" Grid.Row="2" HorizontalAlignment="Left" VerticalAlignment="Top"/>
            <Label x:Name="lblDate" Content="lblDate" Grid.Column="1" HorizontalAlignment="Left" d:LayoutOverrides="Height"/>
            <Label Content="lblEmployee" Grid.Column="1" HorizontalAlignment="Left" Grid.Row="1" d:LayoutOverrides="Height" Name="lblEmployee" />
            <TextBox x:Name="txtNotes" Grid.Column="1" Grid.Row="2" TextWrapping="Wrap" d:LayoutOverrides="Width" LostFocus="txtNotes_LostFocus" />
        </Grid>
        <Button x:Name="btnDelete" HorizontalAlignment="Right" Margin="0,8,8,0" VerticalAlignment="Top">
        </Button>
        <Button x:Name="btnAdd" HorizontalAlignment="Right" Margin="0,8,50,0" VerticalAlignment="Top" Click="btnAdd_Copy_Click">
        </Button>
    </Grid>
</UserControl>

User Control CS用户控制 CS

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;

namespace WinformsWPF
{
    /// <summary>
    /// Interaction logic for ucNotes.xaml
    /// </summary>
    public partial class ucNotes : UserControl
    {
        List<noteItem> notes;
        List<string> noteColumns;
        public ucNotes()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            notes = new List<noteItem>
            {
                new noteItem{nID = 0, nDate = Convert.ToDateTime("9/5/2012 2:48 PM"), nEmployee = "Gardner, John", nText = "This is a test note"},
                new noteItem{nID = 1, nDate = Convert.ToDateTime("9/5/2012 2:51 PM"), nEmployee = "Gardner, John", nText = "This is another test note.  This test note is very long.  It should cause overlap."}
            };
            noteColumns = new List<string> { "nDate", "nEmployee", "nText" };

            dgNotes.GenerateColumns(noteColumns);
            dgNotes.ItemsSource = notes;

        }

        private void dgNotes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            noteItem noteInfo = (noteItem)dgNotes.SelectedItem;
            lblDate.Content = noteInfo.nDate;
            lblEmployee.Content = noteInfo.nEmployee;
            txtNotes.Text = noteInfo.nText;
        }

        private void txtNotes_LostFocus(object sender, RoutedEventArgs e)
        {
            ((noteItem)dgNotes.SelectedItem).nText = txtNotes.Text;
            dgNotes.Items.Refresh();
        }

        private void btnAdd_Copy_Click(object sender, RoutedEventArgs e)
        {
            notes.Add(new noteItem { nDate = DateTime.Now, nEmployee = "Gardner, John" });
            dgNotes.SelectedIndex = dgNotes.Items.Count - 1;
            dgNotes.Items.Refresh();
            txtNotes.Focus();
        }
    }
    public static class dataGridExtension
    {
        public static void GenerateColumns(this DataGrid dataGrid, List<string> columns)
        {
            List<DataGridColumn> oldColumns = dataGrid.Columns.ToList();
            dataGrid.Columns.Clear();

            int index = 0;
            foreach (var column in oldColumns)
            {
                var newCol = (DataGridTextColumn)column;
                newCol.Binding = new Binding(columns[index++]);
                dataGrid.Columns.Add(newCol);
            }
        }
    }
    public class noteItem
    {
        public int nID { set; get; }
        public DateTime nDate { set; get; }
        public string nEmployee { set; get; }
        public string nText { set; get; }
    }
}

The windows form is empty except for the ElementHost (ie, it's a fresh project with nothing changed).除了 ElementHost 之外,windows 窗体是空的(即,它是一个没有任何更改的新项目)。 Let me know if you would like that code as well.如果您也想要该代码,请告诉我。

Any help would be appreciated.任何帮助,将不胜感激。

You inadvertently had IsHitTestVisible="False" set on the UserControl ....take that off and it works.您不经意间在UserControl上设置了IsHitTestVisible="False" ....去掉它,它就可以工作了。

That will stop the control getting mouse messages when hit.这将阻止控件在点击时获取鼠标消息。

I have encountered this issue too, however the accepted solution did not work.我也遇到过这个问题,但是接受的解决方案不起作用。 For posterity I will add what I found out here.为了后代,我将添加我在这里发现的内容。

TLDR TLDR

Disable XAML Hot Reload in Visual Studio.在 Visual Studio 中禁用 XAML 热重载。

Debug -> Options -> Debugging -> Hot Reload -> Uncheck Enable XAML Hot Reload

Problem问题

I have a WPF UserControl hosted in a WinForms project in an ElementHost control.我在ElementHost控件的 WinForms 项目中托管了一个 WPF UserControl。 The WPF UserControl contains a number of labels and textboxes along with two buttons, Save and Cancel. WPF 用户控件包含许多标签和文本框以及两个按钮,保存和取消。

The problem is fairly similar to OPs: You can navigate the UserControl with the tab key and can fire the Click event on the buttons with the space bar.该问题与 OP 非常相似:您可以使用 Tab 键导航UserControl ,并可以使用空格键触发按钮上的 Click 事件。 Hovering over the buttons with the mouse causes the focus color to flash almost imperceptibly and the click event will only be raised if you happen to click at the exact moment the Button has focus.将鼠标悬停在按钮上会导致焦点颜色几乎在不知不觉中闪烁,并且仅当您碰巧在Button具有焦点的那一刻单击时才会引发单击事件。

It looks like something on the UserControl is "stealing" back focus after mouse movement ends, and apparently buttons can only be clicked if they have focus in WPF.看起来UserControl上的某些东西在鼠标移动结束后“窃取”了后焦点,显然只有在 WPF 中有焦点时才能单击按钮。 That something turns out to be the debugger and Hot Reload.东西原来是调试器和热刷新。

Another hint that this problem can also be caused by the debugger is that disabling Hot Reload also solved another issue I had: the WinForms components of the project will loose their DPI-awareness and cause all sorts of wonky issues with presentation. 这个问题也可能由调试器引起的另一个提示是,禁用热重载也解决了我遇到的另一个问题:项目的 WinForms 组件将失去它们的 DPI 感知能力,并导致各种奇怪的演示问题。

Edit: not caused by Hot Reload.编辑:不是由热重载引起的。 Everything else is as described.其他一切都和描述的一样。

For reference I am using Visual Studio Professional 2019 (Version 16.8.2)作为参考,我使用的是 Visual Studio Professional 2019(版本 16.8.2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 WPF不在WinForms中的ElementHost中出现 - WPF Does Not Appear Within ElementHost in WinForms WinForms 中 WPF Elementhost 的自动调整大小无法正常工作 - Autosize of WPF Elementhost in WinForms not working properly 如何在Winforms / WPF中创建透明ElementHost - How to create Transparent ElementHost's in Winforms/WPF 变音符号和使用TAB更改Winforms ElementHost中WPF应用程序主机中的焦点 - Diacritics and using TAB to change focus in a WPF application hostet in Winforms ElementHost 如何从WinForms ElementHost中托管的WPF UserControl获取对Window的引用 - How to get a reference to the Window from a WPF UserControl hosted in a WinForms ElementHost 如何在 Winforms 窗体和由 Winforms 窗体中的 elementhost 托管的 WPF 用户控件之间使用委托? - How to use a delegate between a Winforms Form and a WPF Usercontrol hosted by an elementhost in the Winforms form? 在WPF TextBox上捕获鼠标单击 - Capture mouse clicks on WPF TextBox WinForms禁用双击并接受所有鼠标点击? - WinForms disable double clicks and accept all mouse clicks? 防止表单接收鼠标点击 - Prevent form from receiving mouse clicks 从C#Winforms上的elementhost中托管的RichText wpf控件获取文本 - Get text from RichText wpf control hosted in elementhost on Winforms in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM