3

我有一个想要添加 WPF 用户控件的 winforms 应用程序。问题是当我运行程序时,WPF 用户控件不响应鼠标事件。我可以浏览控件并很好地使用键盘,但是控件不响应鼠标单击(当您将鼠标悬停在按钮上时,按钮甚至无法识别)。我在这个 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 之外,windows 窗体是空的(即,它是一个没有任何更改的新项目)。让我知道您是否也想要该代码。

任何帮助,将不胜感激。

4

2 回答 2

3

你无意中IsHitTestVisible="False"设置了UserControl....把它取下来,它就起作用了。

这将阻止控件在点击时获取鼠标消息。

于 2012-09-07T14:45:37.150 回答
0

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

TLDR

在 Visual Studio 中禁用 XAML 热重载。

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

问题

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

该问题与 OP 非常相似:您可以UserControl使用 tab 键导航,并且可以使用空格键触发按钮上的 Click 事件。Button将鼠标悬停在按钮上会导致焦点颜色几乎无法察觉地闪烁,并且仅当您恰好在具有焦点的那一刻单击时才会引发单击事件。

鼠标移动结束后,似乎有东西在UserControl“窃取”后焦点,显然只有在 WPF 中有焦点时才能单击按钮。原来是调试器和热重载。

这个问题也可能由调试器引起的另一个提示是,禁用热重载也解决了我遇到的另一个问题:项目的 WinForms 组件将失去 DPI 意识,并导致各种显示问题。

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

作为参考,我正在使用 Visual Studio Professional 2019(版本 16.8.2)

于 2020-12-08T08:04:32.967 回答