WPF ElementHost在WinForms中无法接收鼠标点击

3
我有一个winforms应用程序,想要添加一个WPF用户控件。问题在于当我运行程序时,WPF用户控件无法响应鼠标事件。我可以通过控件进行Tab操作并使用键盘,但是控件不会响应鼠标点击(按钮甚至不能识别鼠标悬停)。我尝试了这个SO问题中的解决方案,但没有帮助:WPF WinForms Interop issue with Enable / Disable。请查看下面的代码。
用户控件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>

用户控件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; }
    }
}

窗体除了ElementHost为空(即没有更改的新项目)。 如果您需要该代码,请告诉我。任何帮助将不胜感激。
2个回答

3

就是这样!我不确定那是怎么进去的,但我想那一定是像那个小属性一样引起了所有问题。谢谢! - jmgardn2

0

我也遇到了这个问题,但是被接受的解决方案并没有起作用。为了后人,我将在这里添加我发现的内容。

TLDR

在Visual Studio中禁用XAML热重新加载。

调试 -> 选项 -> 调试 -> 热重新加载 -> 未勾选启用XAML热重新加载

问题

我有一个WPF UserControl托管在WinForms项目中的ElementHost控件中。WPF UserControl包含许多标签和文本框以及两个按钮:保存和取消。

问题与OPs相当相似:您可以使用tab键浏览UserControl,并且可以使用空格键触发按钮的单击事件。使用鼠标悬停在按钮上导致焦点颜色几乎不可感知地闪烁,并且只有在您恰好在Button具有焦点的时刻单击事件才会被触发。

看起来像是UserControl上的某些东西在鼠标移动结束后“夺回”焦点,并且显然在WPF中只有当它们具有焦点时才能单击按钮。那个某些东西就是调试器和热重新加载。

另一个提示是,调试器也可能导致此问题,因为禁用热重新加载还解决了我遇到的另一个问题:项目的WinForms组件将失去其DPI感知性并导致所有种类的漂移问题。

编辑:不是由热重新加载引起的。其他一切如描述所述。

供参考,我使用的是Visual Studio Professional 2019(版本16.8.2)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接