【问题标题】:Button in a column, getting the row from which it came on the Click event handler列中的按钮,在 Click 事件处理程序中获取它来自的行
【发布时间】:2009-07-23 00:26:30
【问题描述】:

我已将 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 中添加一些额外的东西,或者我可能会绕道而行?任何帮助/建议表示赞赏。

【问题讨论】:

    标签: c# wpf xaml datagrid datagridview


    【解决方案1】:

    基本上,您的按钮将继承行数据对象的数据上下文。我称它为 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
    }
    

    【讨论】:

    • 做这类事情的理想方法是使用命令(基本上是 MVVM 模式),您可以在数据对象(ViewModel)中创建命令并调用 Button.Command ,这样就不会有任何代码后面喜欢按钮点击。
    • @JobiJoy:你有使用命令/中继命令的例子吗?我正在尝试一些事情,但无法让它发挥作用..
    • 我看到的命令示例的问题是您必须将数据网格选定项数据绑定到视图模型的成员,因此很难将命令泛化到足以用于删除按钮。我想要一个删除按钮模板列资源,我可以用它来删除我的应用程序中的几乎所有内容。
    【解决方案2】:

    我喜欢这样做的另一种方法是将 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;
    }
    

    【讨论】:

    • 你为什么要混淆事件和命令?使用命令并在其中使用命令参数。
    • 3 个答案:为什么不呢?简单。 OP 询问的是事件处理程序,而不是命令。命令可能是矫枉过正。使用CommandParameter 可能不是该属性的预期用途,但在语义上,它比使用Tag 更有意义,并且比从处理程序中的绑定对象中检索ID 更简单。如果您更喜欢命令,那么这种方法很好,但如果您不打算使用它,为什么还要增加复杂性呢?
    【解决方案3】:

    另一种绑定到命令参数 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 会在模型中,还是将按钮的数据上下文重置为 ViewModel?
    • @PetrŠebesta “RowActionCommand 在每个行视图模型中定义。”这没有任何意义。但无论如何,很好的解决方案。
    【解决方案4】:
    MyObject obj= (MyObject)((Button)e.Source).DataContext;
    

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

      • 应该是e.OriginalSource。而不是e.Source
      • Seriously Bigeyes,我的回答来自真实、实时、可工作的代码!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 2015-07-02
      相关资源
      最近更新 更多