Reputation: 961
I have a winforms application that I'd like to add a WPF user control to. The issue is when I run the program the WPF user control does not respond to mouse events. 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 . Please see the code below.
User Control 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
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). Let me know if you would like that code as well.
Any help would be appreciated.
Upvotes: 3
Views: 2681
Reputation: 76
I have encountered this issue too, however the accepted solution did not work. For posterity I will add what I found out here.
Disable XAML Hot Reload in Visual Studio.
Debug -> Options -> Debugging -> Hot Reload -> Uncheck Enable XAML Hot Reload
I have a WPF UserControl hosted in a WinForms project in an ElementHost
control. The WPF UserControl contains a number of labels and textboxes along with two buttons, Save and Cancel.
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. 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.
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. 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.
Edit: not caused by Hot Reload. Everything else is as described.
For reference I am using Visual Studio Professional 2019 (Version 16.8.2)
Upvotes: 0
Reputation: 12540
You inadvertently had IsHitTestVisible="False"
set on the UserControl
....take that off and it works.
That will stop the control getting mouse messages when hit.
Upvotes: 3