DataGrid Button Column

Nov 17, 2008 at 2:53 PM

Hi,

I'd like to add a button column to a datagrid, with the Button's visibility bound to one of Item's properties.

Please does anyone know how to do this, and also how to access the row's Item from inside the Button's Click event handler?

Thanks,

Alonzo
Coordinator
Nov 18, 2008 at 12:45 PM

 

 

<dg:DataGridTemplateColumn Header="Edit Row">
    <dg:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Content="Edit" Click="EditButton_Click" />
        </DataTemplate>
    </dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>

 

private

 

void EditButton_Click(object sender, RoutedEventArgs e)
{
    //Open the current row for edit
    DataGrid_Standard.BeginEdit();
}


In this code I directly use my DataGrid instance but if you really wanted to find the current item on the row you can walk up the tree starting with the sender and look for DataGridRow.  When you find that you will be able to have access to the row Item.

Nov 23, 2008 at 7:14 PM

Thanks, vinsibal, that's very helpful.  I was able to get a button column quite easily with the DataTemplate you described.

Now all I need is a way to bind the visiblilty of the button to a bool property on the Item.

I think it would start something like this

                DataTrigger t = new DataTrigger();
                Binding tbind = new Binding();
                t.Binding = tbind;
                tbind.RelativeSource = new RelativeSource();
                tbind.RelativeSource.AncestorLevel = 1;
                tbind.RelativeSource.AncestorType = typeof(myItemType);

Is this the right idea, or is there an easier way?

Alonzo

Coordinator
Dec 3, 2008 at 12:44 PM
Were you able to successfully do the binding?  I would think you would need to correct data context.  Jaime wrote this nice post about how to do that, http://blogs.msdn.com/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx.
Dec 3, 2008 at 1:33 PM
Hi again, thanks for taking an interest.

As I am writing a generic GUI class, I'm trying to do everything in code.  At first I was stumped by not knowing how to call SetBinding on a DataTemplate element.

After using the datatemplate and datagridtemplatecolumn as you suggested, I was able to bind back to item properties using a data trigger.  For example, to set the foreground colour of the button,
I used a binding like this, where Status is the Item property I'm looking for.

            DataTrigger t = new DataTrigger();
            Binding b = new Binding("Item.Status");
            b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor);
            b.RelativeSource.AncestorType = typeof(DataGridRow);
            t.Binding = b;
            b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            t.Value = "Error";
            t.Setters.Add
                (new Setter(Control.ForegroundProperty, Brushes.Red));

Then I applied the datatrigger to the CellStyle of the column; this worked great.
                Style st = new Style(typeof(DataGridCell));
                st.Triggers.Add(t);
                myColumn.CellStyle = st;

I couldn't set the click handler for the datatemplate button directly the way you suggested, but I was able to cheat using a button style.
            EventSetter es = new EventSetter(Button.ClickEvent,
                new RoutedEventHandler(Button_Click));
            Style stb = new Style(typeof(Button));
            stb.Setters.Add(es);
            myDataGrid.Resources.Add(typeof(Button), stb);

And then I used the datagrid reference as you suggested to get the row whose button was pressed in the Button_Click event handler.  If I had more than 1 button column, I could still use this as I could get the column as well.

I hope all this might help someone else.

Alonzo