在列中单击按钮,获取它来自Click事件处理程序的行


97

我已经将WPF Datagrid的itemsource设置为从DAL返回的对象列表。我还添加了一个额外的列,其中包含一个按钮,下面是xaml。

<toolkit:DataGridTemplateColumn  MinWidth="100" Header="View">
    <toolkit:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Click="Button_Click">View Details</Button>
        </DataTemplate>
    </toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>

这很好。但是,在Button_Click方法上,有什么方法可以让我在按钮所在的数据网格上获取行?更具体地说,我对象的属性之一是“ Id”,我希望能够将其传递到事件处理程序中另一种形式的构造函数中。

private void Button_Click(object sender, RoutedEventArgs e)
    {
        //I need to know which row this button is on so I can retrieve the "id"  
    }

也许我在xaml中需要一些额外的东西,或者我正在以一种回旋的方式来解决这个问题?任何帮助/建议表示赞赏。

Answers:


128

基本上,您的按钮将继承行数据对象的datacontext。我将其称为MyObject,希望MyObject.ID是您想要的。

private void Button_Click(object sender, RoutedEventArgs e)
{
    MyObject obj = ((FrameworkElement)sender).DataContext as MyObject;
    //Do whatever you wanted to do with MyObject.ID
}

7
进行此类操作的理想方法是使用命令(基本上是MVVM模式),您可以在数据对象(ViewModel)中创建一个命令并调用Button.Command,这样就不会像按钮单击那样隐藏任何代码。
Jobi Joy

1
@JobiJoy:您是否有使用Command / RelayCommand的示例?我尝试一些东西,但它不能获得工作..
VoodooChild

我所看到的命令示例的问题在于,您必须将datagrid选定的项目数据绑定到视图模型的成员,因此很难足够泛化该命令以适合于删除按钮。我想要一个删除按钮模板列资源,可以用来删除应用程序中的几乎所有内容。
埃里克

47

我喜欢这样做的另一种方法是将ID绑定到按钮的CommandParameter属性:

<Button Click="Button_Click" CommandParameter="{Binding Path=ID}">View Details</Button>

然后,您可以像在代码中那样访问它:

private void Button_Click(object sender, RoutedEventArgs e)
{
    object ID = ((Button)sender).CommandParameter;
}

您为什么要混合事件和命令?使用命令并在其中使用命令参数。
ProfK

1
3个答案:为什么不呢?简单。OP正在询问事件处理程序,而不是命令。命令可能会过大。使用CommandParameter可能不是该属性的预期用途,但从语义上讲,它比使用更有意义,Tag而且比从处理程序中的绑定对象中检索ID更简单。如果您更喜欢Commands,那么这种方法很好,但是如果您不打算使用它,为什么还要增加复杂性呢?
xr280xr

10

绑定到命令参数DataContext并尊重MVVM的另一种方式,如Jobi Joy所说的按钮,继承了datacontext表单行。

XAML中的按钮

<RadButton Content="..." Command="{Binding RowActionCommand}" 
                         CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}"/>

命令执行

public void Execute(object parameter)
    {
        if (parameter is MyObject)
        {

        }
    }

因此,将RowActionCommand包含在Model中还是将按钮的datacontext重置为ViewModel?
汤姆·帕迪拉

@PetrŠebesta“ RowActionCommand在每个行视图模型中定义。” 这没有任何意义。但是无论如何,不​​错的解决方案。
伊戈尔2015年

4
MyObject obj= (MyObject)((Button)e.Source).DataContext;

0

如果您的DataGrid的DataContext是一个DataView对象(DataTable的DefaultView属性),那么您也可以这样做:

private void Button_Click(object sender, RoutedEventArgs e) {
   DataRowView row = (DataRowView)((Button)e.Source).DataContext;
}

应该是e.OriginalSource。代替e.Source
Bigeyes

说真的,Bigeyes,我的回答来自真实,实时,有效的代码!
SurfingSanta
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.