简体   繁体   English

DataGrid和按钮:未调用的事件处理程序

[英]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 . 我有一个StackPanel有一个DataGrid绑定到DataSet在它和Grid下面DataGrid在底部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 . Grid包含一个Button ,在用户更改了DataGrid的内容之后,我想使用它来更新与DataSet关联的DataAdapter

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. 如果我更改了数据网格中的现有行,然后单击按钮,或者如果我在网格的最后一行(空)中输入值,然后按Enter,最后单击按钮,则此方法有效。 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. 如果我在网格的最后一行中输入值并且不按Enter键,则单击该按钮将在数据网格底部产生一个新的(空)行,并且不会调用事件处理程序。 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 DataSet somehow 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. 我的第一个怀疑是需要以某种方式通知DataSet有关新数据,但是如果我添加新行,请按Enter键并添加第二行新内容,那么单击按钮也不会导致事件处理程序的调用,这意味着我的怀疑并不能解释这种行为。

This is using Visual Studio Express 2012 这是使用Visual Studio Express 2012

Here is the XAML : 这是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: (我计划添加更多按钮,因此网格上会有更多列)(在“ Window”后面的代码定义了如下绑定):

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. 编辑:万一重要,该窗口称为对话框。

I think you should check and see if DataGrid is in edit mode or not. 我认为您应该检查并查看DataGrid是否处于编辑模式。

Handle these two events in your dataGrid: BeginningEdit and CellEditEnding (or maybe in your case RowEditEnding ) 处理dataGrid中的以下两个事件: BeginningEditCellEditEnding (或者在您的情况下为RowEditEnding

define this property public bool IsInEditMode; 定义此属性public bool IsInEditMode; and : 和:

void dg_BeginningEdit(object sender, BeginningEditEventArgs e)
{
    IsInEditMode=true;
}

void dg_CellEditEnding(object sender, CellEditEndingEventArgs e)
{
    IsInEditMode=false;
}

Now you can determine when you are in edit mode, when the Button is pressed: 现在,您可以确定何时按下按钮时处于编辑模式:

 void buttonUpdate_Click_1(...)
 {
      if (IsInEditMode)
       {
           producerDataGrid.CommitEdit();
       }
  }

see CommitEdit method. 请参见CommitEdit方法。 We call it to end edit. 我们称其为结束编辑。

I figured out how to change the behaviour I described with the help of an article on this MS page . 我想出了如何借助此MS页面上的文章来更改我描述的行为。 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: 我向按钮的MouseDownEvent添加了一个处理函数,即使e.Handled属性设置为true,该处理函数也会被调用,如下所示:

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). 最后的true可以解决问题,并且在XAML中分配的处理程序现在根本没有调用过(因此,新的处理程序似乎首先被调用,并且以某种方式神奇地将event.Handled设置为true ,但是我不知道)不知道我是否可以依靠它。因为两次调用update函数都没有害处,所以这对我来说很好。 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 http://msdn.microsoft.com/zh-CN/magazine/cc785480.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM