Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WIndows Forms Chart in WindowsFormsHost does not receive mouse wheel?

i have a Forms.DataVisualization.Charting.Chart in a WindowsFormsHost. I can't get the chart to receive mouse wheel events. Clicks are working, if i try with a Forms.TextBox the mouse wheel is working, too. The mouse wheel is also working if i use the chart in a "native" forms app.

So, what makes the problem is the combination of the forms chart in a formsHost.

Here is a verry simple application to replicate the problem:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Name="TextBlock1" Grid.Column="1" />
    <WindowsFormsHost Name="WindowsFormsHost1" Grid.Column="0"/>
</Grid>

and the code behind:

public MainWindow()
    {
        InitializeComponent();

        var chart = new Chart() { BackColor = System.Drawing.Color.Aquamarine};
        WindowsFormsHost1.Child = chart;

        chart.MouseDown += (a, b) => TextBlock1.Text += "FORMS click\r\n";
        TextBlock1.MouseDown += (a, b) => TextBlock1.Text += "WPF click\r\n";

        chart.MouseWheel += (a, b) => TextBlock1.Text += "FORMS wheel\r\n";
        TextBlock1.MouseWheel += (a, b) => TextBlock1.Text += "WPF wheel\r\n";
    }

i can receive all clicks and the mouse wheel from wpf, but no wheel from forms. I tried the wheel listener of the formsHost as well, without success.

Any ideas? Jon Skeet?

like image 766
Martin Booka Weser Avatar asked Sep 14 '11 09:09

Martin Booka Weser


1 Answers

This is a common interoperability problem between Windows Forms (WinForms) and WPF. WPF events behave differently, they use routed event instead of the old event handling of Windows Forms.

WinForms itself is a map of message handling from Win32 world, therefore you have to code it manually when embedding WindowsForms control on WPF. In order to handle mouse event other than mouse click (this including mouse wheel), you have to surrogate the winforms event.

MSDN library of .NET 4 mentioned this clearly:

Surrogate Windows Forms Message Loop

By default, the System.Windows.Forms.Application class contains the primary message loop for Windows Forms applications. During interoperation, the Windows Forms message loop does not process messages. Therefore, this logic must be reproduced. The handler for the ComponentDispatcher.ThreadFilterMessage event performs the following steps:

1.Filters the message using the IMessageFilter interface.

2.Calls the Control.PreProcessMessage method.

3.Translates and dispatches the message, if it is required.

4.Passes the message to the hosting control, if no other controls process the message.

When the window handle is destroyed, the WindowsFormsHost control removes itself from registration.

For more info, visit: http://msdn.microsoft.com/en-us/library/ms742474.aspx

like image 75
Eriawan Kusumawardhono Avatar answered Nov 15 '22 07:11

Eriawan Kusumawardhono