0

I want to add a button into each row of a DataGrid, which should programmatically be disabled / renamed.

I found out, that it is possible to add a button doing the following:

<DataGrid x:Name="dataGrid_newViews" ItemsSource="{Binding}" AutoGenerateColumns="True" CanUserAddRows="false" Grid.ColumnSpan="2">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button x:Name="btn_installSnippet" Click="btn_installSnippet_Click">Install</Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

When I try to do something like

btn_installSnippet.Content = "abc";

I do get the error message, that the name does not exist in the current context...

Can anybody give me a hint, what I am doing wrong?

OhBeWise
  • 5,350
  • 3
  • 32
  • 60
Gardinero
  • 331
  • 2
  • 13
  • Since there is a `Button` on each row, do you programmatically want to disable all of the buttons or just anyone of them? – mm8 Sep 15 '20 at 14:05
  • The software checks a folder for some files containing XML snippets. Those are listed in the DataGrid. Each button in each row should behave individually, depending on, if the snippet is already included in another big XML file, or not. – Gardinero Sep 16 '20 at 09:19

2 Answers2

1

The DataTemplate definition in the XAML:

<Window 
     ... 
     MouseDoubleClick="Window_MouseDoubleClick">

     <Grid>
            <Grid.Resources>
                <DataTemplate x:Key="ButtonTemplate" >
                    <Button x:Name="btn_installSnippet" Click="btn_installSnippet_Click">Install</Button>
                </DataTemplate>
            </Grid.Resources>
            <DataGrid x:Name="dataGrid_newViews" ItemsSource="{Binding}" AutoGenerateColumns="True" CanUserAddRows="True" Grid.ColumnSpan="2">
                <DataGrid.Columns>
                    <DataGridTemplateColumn Header="Button" CellTemplate="{StaticResource ButtonTemplate}" />
                </DataGrid.Columns>
            </DataGrid>
     </Grid>
</Window>

Adding a new row in the code behind:

private void Window_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    dataGrid_newViews.Items.Add("a new item");         
}

NOTE: The System.Windows.Media.VisualTreeHelper might be used to iterate all elements in the DataGrid to find out required control.

Jackdaw
  • 7,626
  • 5
  • 15
  • 33
-1

For maximum control you can do everything in code behind:

DataGridTemplateColumn column = new DataGridTemplateColumn();
column.Header = "NewColumn";
FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Button));
string content = "MyContent";
factory.SetValue(Button.ContentProperty, content);
DataTemplate cellTemplate = new DataTemplate();
cellTemplate.VisualTree = factory;
column.CellTemplate = cellTemplate;
dg1.Columns.Add(column);

You can see more details here: What is the code behind for datagridtemplatecolumn, and how to use it?

SAR
  • 180
  • 1
  • 9
  • This doesn't offer more control, but more complexity. [`FrameworkElementfactory`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.frameworkelementfactory?view=netcore-3.1#remarks): This class is a deprecated way to programmatically create templates (see remarks in docs). – BionicCode Sep 15 '20 at 09:45