views:

149

answers:

1

I didn't know how to make the 'issue' (different behavior) more clear in the title, but I'll explain here.

In our WPF application, we're using the DataGrid control to list a number of entities. After double clicking a row, we open a new Window and in that Window, there are among other things a couple of MenuItem controls.

The problem is that when the Window opens on a position where one of the menu items is right under the mouse pointer, the menu item is actually clicked there at the mouse up of the double click.

When we use a button instead, the button click event is not fired automatically in the same situation.

We are now thinking about using buttons instead of menu items (or creating custom menus), but perhaps someone here has an explanation or solution to alter this behavior? Personally, I can't think of a case where this would be beneficial at all. Thanks in advance!

Example code is below. To see what I mean, double click the DataGrid row to open the new window and hold down the mouse button, move to the menu item and let the mouse button go (in TestWindow.xaml, exchange the MenuItem for a Button control to see the difference in behavior):

MainWindow.xaml

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <Style x:Key="DataGridRowStyle"
           TargetType="{x:Type DataGridRow}">
        <EventSetter Event="MouseDoubleClick" Handler="DataGridRow_MouseDoubleClick" />
    </Style>
</Window.Resources>
<DataGrid RowStyle="{StaticResource DataGridRowStyle}" x:Name="MyDataGrid">
    <DataGrid.Columns>
        <DataGridTextColumn Header="String" Binding="{Binding}" IsReadOnly="True" />
    </DataGrid.Columns>
</DataGrid>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        ObservableCollection<string> myCollection = new ObservableCollection<string>();

        myCollection.Add("test");

        MyDataGrid.ItemsSource = myCollection;

        this.DataContext = this;
    }

    private void DataGridRow_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        TestWindow window = new TestWindow();
        window.Show();
        window.Activate();
    }
}

TestWindow.xaml

<Window x:Class="WpfApplication2.TestWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="TestWindow" Height="300" Width="300">
<Grid>
    <MenuItem Header="Test" Click="Button_Click" />
</Grid>

TestWindow.xaml.cs

public partial class TestWindow : Window
{
    public TestWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }
}
A: 

You could try modifying your DataGridRow_MouseDoubleClick handler as follows:

private void DataGridRow_MouseDoubleClick( object sender, MouseButtonEventArgs e )
{
    this.Dispatcher.BeginInvoke(
        ( Action )delegate
        {
            TestWindow window = new TestWindow();
            window.Show();
            window.Activate();
        },
        System.Windows.Threading.DispatcherPriority.Background,
        null
        );
}

That might solve the problem by letting the outstanding events "settle" before creating the new window.

Adel Hazzah
Thanks for the answer, but it doesn't work. Not the nicest solution either if it would work, but then again, it seems like a nice solution might not be there. ;)