Search code examples
c#wpfxamlclickwpfdatagrid

DataGrid and button: event handler for click not called


I have a StackPanel with a DataGrid bound to a DataSet in it and a Grid below the DataGrid at the bottom of the StackPanel. The Grid holds a Button which I want to use to update the DataAdapter associated with the DataSet after the user changed the content of the DataGrid.

This mostly works as expected, but not always.

My expectation is that the eventhandler is called whenever I click the button. This does work if I change an existing line in the data grid and then click the button, or if I enter values in the last (empty) line of the grid, then press enter and finally click the button. If I enter values in the last line of the grid and do not press enter, clicking the button results in a new (empty) line at the bottom of the data grid and the eventhandler is not called. Only by clicking it a second time the event handler is called. Why is this? Can I change this?

My first suspicion was that the DataSetsomehow needs to be informed about new data, but if I add a new line, press enter and add a second new line then the button click also does not result in a call to the event handler, which implies that my suspicion does not explain the behaviour.

This is using Visual Studio Express 2012

Here is the XAML:

<Window x:Class="AppVer0._01.ProducerWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Producer" Height="300" Width="300">
  <StackPanel>
    <DataGrid ItemsSource="{Binding producer}"    
              AutoGenerateColumns="True"
              HorizontalAlignment="Left"
              Name="producerDataGrid"
              />
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <Button Name="buttonUpdate" Click="buttonUpdate_Click_1">Aktualisieren</Button>
    </Grid>
  </StackPanel>
</Window>

(I plan to add more buttons, so the grid has some more columns) The code behind (for `Window) defines the binding as follows:

DataSet ds = new DataSet();
// ...
// load data from adapter into dataset
// 
this.DataContext = ds;

and there is, of course, the eventhandler defined.

Edit: In case that matters, the window is called as a dialog.


Solution

  • I figured out how to change the behaviour I described with the help of an article on this MS page. I added a handler to the MouseDownEvent of the button which will be called even when the e.Handled attribute has been set to true, as follows:

    buttonUpdate.AddHandler(UIElement.MouseDownEvent,
            (RoutedEventHandler)buttonUpdate_ClickAlwaysCalled, true);
    

    The true at the end does the trick, and the handler which has been assigned in the XAML is now no langer called at all (so the new handler seems to get called first and somehow magically sets event.Handled to true, but I don't know whether I can rely on this. Since calling the update function twice does no harm this is fine for me). I'm not sure whether this is a good way of doing this, but it does work.

    http://msdn.microsoft.com/en-us/magazine/cc785480.aspx