WPF:向Datagrid添加按钮列

时间:2009-11-18 10:41:45

标签: wpf datagrid

你好我怎么能以编程方式将一个Button列添加到Datagrid。我想通过代码隐藏文件中的代码来实现这一点。

此外,我想根据记录选择性地启用或禁用此按钮(如果状态为打开,则启用它,否则禁用此按钮)。这里Status是DataSource中的一个列。

谢谢, ABHI

3 个答案:

答案 0 :(得分:5)

viky链接的答案总结了从源添加按钮列的想法。我已经汇总了一个简短的示例,其中还显示了问题的第二部分,即如何根据网格中的数据启用/禁用按钮。我在4.0中使用了DataGrid,但3.5的工具包也应该没问题。

首先,我从XAML添加一个Name列。这不是必需的,但只是表明您可以将XAML和C#添加组合到网格中。请注意,我在这里命名网格,以便我可以在C#partial类中引用它。

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Data Grid Populated in XAML and C#">
    <Grid>
        <DataGrid x:Name="_gridControl" IsReadOnly="True" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Width="*" Binding="{Binding Name}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

现在,我在后面的代码中做了两件事。除了添加按钮列和数据元素(具有Name和Status)之外,我创建了一个Converter类,如果值为“Open”则返回true,否则返回false。然后,当设置Binding(而不是值)时,我还添加了我的转换器,以便在ItemsControl生成并绑定我的项目的容器时,显示的Button将其IsEnabled状态链接到我的项目的Status字段。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var buttonTemplate = new FrameworkElementFactory(typeof(Button));
        buttonTemplate.SetBinding(Button.ContentProperty, new Binding("Name"));
        buttonTemplate.SetBinding(Button.IsEnabledProperty, new Binding("Status")
        {
            Converter = new StatusToEnabledConverter()
        });
        buttonTemplate.AddHandler(
            Button.ClickEvent, 
            new RoutedEventHandler((o, e) => MessageBox.Show("hi"))
        );
        this._gridControl.Columns.Add(
            new DataGridTemplateColumn()
            {
                Header = "Close Button",
                CellTemplate = new DataTemplate() { VisualTree = buttonTemplate }
            }
        );

        this._gridControl.ItemsSource = new object[]
        {
            new { Name = "First Item", Status = "Open" },
            new { Name = "Second Item", Status = "Open" },
            new { Name = "Third Item", Status = "Closed" },
            new { Name = "Fourth Item", Status = "Closed" },
            new { Name = "Fifth Item", Status = "Open" }
        };
    }
}

public class StatusToEnabledConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        return "Open".Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        throw new System.NotImplementedException();
    }
}

最后一个重要的注意事项是,我只在调用InitializeComponent后从C#修改DataGrid。对于具有XAML和C#部分的WPF内容控件,这很重要,因为在开始修改XAML中定义的对象之前,需要完成通过XAML完成的对象构造。

希望这有帮助!

答案 1 :(得分:1)

Xaml:

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

隐藏代码

       private IEnumerable<DataGridRow> GetDataGridRowsForButtons(DataGrid grid)
    { //IQueryable 
        var itemsSource = grid.ItemsSource as IEnumerable;
        if (null == 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;
        }
    }

    void Details(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;
            }
    }

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

答案 2 :(得分:0)

XAML:

  <DataGrid.Columns>
                <DataGridTemplateColumn Header="Check">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox  x:Name="chkName" IsChecked="{Binding IsChecked ,  UpdateSourceTrigger=PropertyChanged}" Click="chkName_Click">
                            </CheckBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                
                <DataGridTemplateColumn Header="as">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Click="OnAddQuantityClicked">hello</Button>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>

后面的代码:

private async void OnAddQuantityClicked(object sender, RoutedEventArgs e)
        {
            if (sender is Button)
            {
                var temps = (Models.TempV)mainDatagrid.SelectedItem;
                //Button button = (Button)e.OriginalSource;
                if (temps.IsChecked is true)
                {
                    MessageBox.Show("Do something when it is True");
                }
                else
                {
                    MessageBox.Show("Do something when it is False");
                }
            }
        }