向WPF DataGrid添加按钮

67

我想在WPF中创建一个DataGrid控件,在每行的第一个单元格中添加一个按钮。点击该按钮将显示RowDetailsTemplate或子行。

如何添加一个按钮来显示/隐藏RowDetailsTemplate

4个回答

94

首先创建一个 DataGridTemplateColumn 来包含该按钮:

<DataGridTemplateColumn>
  <DataGridTemplateColumn.CellTemplate> 
    <DataTemplate> 
      <Button Click="ShowHideDetails">Details</Button> 
    </DataTemplate> 
  </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn>

当按钮被点击时,更新包含的 DataGridRowDetailsVisibility 属性:

void ShowHideDetails(object sender, RoutedEventArgs e)
{
    for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
    if (vis is DataGridRow)
    {
        var row = (DataGridRow)vis;
        row.DetailsVisibility = 
        row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
        break;
    }
}

这将在第一列添加按钮,最后一列有什么想法吗? - Hassan Ansari
@Hassan Ansari 这将在您放置它的任何位置添加按钮。如果您在其他列之前放置我上面显示的XAML,则按钮将显示为第一列。如果您在所有其他列之后放置XAML,则按钮将显示为最后一列。如果您将其放在中间,则按钮将显示在中间。您可以按任何顺序放置列,按钮可以位于任何列中。 - Ray Burns
我的列是自动生成的,我正在以列的形式获取数据,如datagrid.itemSource = List<MyEntity>。 - Hassan Ansari

36

看一下这个:

XAML:

<DataGrid Name="DataGrid1">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Click="ChangeText">Show/Hide</Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

方法:

private void ChangeText(object sender, RoutedEventArgs e)
{
    DemoModel model = (sender as Button).DataContext as DemoModel;
    model.DynamicText = (new Random().Next(0, 100).ToString());
}

类别:

class DemoModel : INotifyPropertyChanged
{
    protected String _text;
    public String Text
    {
        get { return _text; }
        set { _text = value; RaisePropertyChanged("Text"); }
    }

    protected String _dynamicText;
    public String DynamicText
    {
        get { return _dynamicText; }
        set { _dynamicText = value; RaisePropertyChanged("DynamicText"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler temp = PropertyChanged;
        if (temp != null)
        {
            temp(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

初始化代码:

ObservableCollection<DemoModel> models = new ObservableCollection<DemoModel>();
models.Add(new DemoModel() { Text = "Some Text #1." });
models.Add(new DemoModel() { Text = "Some Text #2." });
models.Add(new DemoModel() { Text = "Some Text #3." });
models.Add(new DemoModel() { Text = "Some Text #4." });
models.Add(new DemoModel() { Text = "Some Text #5." });
DataGrid1.ItemsSource = models;

这似乎与问题无关,问题是如何在单击按钮时显示/隐藏详细行。此代码的作用是在单击按钮时更改模型中的某些数据。 - Ray Burns

4

XAML

<DataGrid x:Name="dgv_Students" AutoGenerateColumns="False" 
          ItemsSource="{Binding People}" Margin="10,20,10,0" 
          Style="{StaticResource AzureDataGrid}" FontFamily="B Yekan" 
          Background="#FFB9D1BA">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Click="RowButton_Click">Text</Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
   </DataGrid.Columns>
</DataGrid>

代码后置

private IEnumerable<DataGridRow> GetDataGridRowsForButtons(DataGrid grid)
{ 
    //IQueryable
    if (!(grid.ItemsSource is IEnumerable itemsSource)) 
        yield return null;

    foreach (var item in itemsSource)
    {
        var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
        if (null != row & row.IsSelected) 
           yield return row;
    }
}

private void RowButton_Click(object sender, RoutedEventArgs e)
{
    for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
        if (vis is DataGridRow)
        {
           // var row = (DataGrid)vis;

            var rows = GetDataGridRowsForButtons(dgv_Students);

            string id;
            foreach (DataGridRow dr in rows)
            {
                id = (dr.Item as tbl_student).Identification_code;
                MessageBox.Show(id);
                break;
            }

            break;
        }
}

点击按钮后,该行的ID将返回给您,您可以将其用于按钮名称。


1
如果你想使用一个命令,你可以使用下面的示例作为基础。
<DataGridTemplateColumn
Header="Action"
>
<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Button 
            VerticalAlignment="Top"
            Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource FindAncestor, 
                AncestorLevel=1, AncestorType={x:Type UserControl}}}" 
            CommandParameter="{Binding .}"
            Content="Delete">                
        </Button>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

检查您的AncestorTyp是否与绑定您的ViewModel的父视图匹配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接