How can I put a DataGridTextColumn or DataGridComboBoxColumn inside of a DataTemplate?

Clayton Davidson 1 Reputation point
2022-02-02T15:14:15.383+00:00

I have a column in a DataGrid that needs to display both textboxes and comboboxes conditionally. To do this, I used a DataTemplate. However, normal TextBox and ComboBox elements do not act the same way as DataGridTextColumn and DataGridComboBoxColumn. For example, I want to be able to press Enter and it skip to the next cell. This is not working with a normal TextBox.

Is there a way to put a DataGridTextColumn or DataGridComboBoxColumn inside of a DataTemplate. Or is there a way to make a TextBox appear as a DataGridTextColumn or ComboBox as a DataGridComboBoxColumn?

I am trying to accomplish something like the following:

<DataGrid.Resources>
  <DataTemplate x:Key="TextBoxTemplate">
    <DataGridTextColumn Binding="{Binding SetupData}" Foreground="DodgerBlue"/>
  </DataTemplate>
  <DataTemplate x:Key="ComboBoxTemplate">
    <DataGridComboBoxColumn Binding="{Binding SetupComboboxData}" Foreground="DodgerBlue"/>
  </DataTemplate>
</DataGrid.Resources>

I receive this error: The root of a Template content section cannot contain an element of type 'System.Windows.Controls.DataGridTextColumn'. Only FrameworkElement and FrameworkContentElement types are valid.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,271 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Hui Liu-MSFT 15,926 Reputation points Microsoft Vendor
    2022-02-03T07:09:11.523+00:00

    It is difficult to put DataGridTextColumn or DataGridComboBoxColumn in DataTemplate.
    If you want to implement editable DataGridComboBoxColumn/DataGridTextColumn column you could refer to the following code.
    MainWindow.xaml:

    <Grid>  
            <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GridItems}" >  
                <DataGrid.Columns>  
                    <DataGridTemplateColumn>  
                        <DataGridTemplateColumn.CellTemplate>  
                            <DataTemplate>  
                                <TextBlock Text="{Binding Name}" Foreground="Pink"/>  
                            </DataTemplate>  
                        </DataGridTemplateColumn.CellTemplate>  
                        <DataGridTemplateColumn.CellEditingTemplate>  
                            <DataTemplate>  
                                <TextBox Text="{Binding Name}" Background="LightBlue"/>  
                            </DataTemplate>  
                        </DataGridTemplateColumn.CellEditingTemplate>  
                    </DataGridTemplateColumn>  
                    <DataGridComboBoxColumn  SelectedValueBinding="{Binding CompanyID}"    DisplayMemberPath="Name"  SelectedValuePath="ID">  
                        <DataGridComboBoxColumn.ElementStyle>  
                            <Style TargetType="{x:Type ComboBox}">  
                                <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />  
                            </Style>  
                        </DataGridComboBoxColumn.ElementStyle>  
                        <DataGridComboBoxColumn.EditingElementStyle>  
                            <Style TargetType="{x:Type ComboBox}">  
                                <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />  
                            </Style>  
                        </DataGridComboBoxColumn.EditingElementStyle>  
                    </DataGridComboBoxColumn>  
                </DataGrid.Columns>  
            </DataGrid>  
        </Grid>  
    

    MainWindow.xaml.cs:

    using System.Collections.ObjectModel;  
    using System.Windows;  
    
    namespace PropertyChangedDemo  
    {  
      public partial class MainWindow : Window  
      {  
        public MainWindow()  
        {  
          InitializeComponent();  
          DataContext= new ViewModel();  
        }  
      }  
      public class GridItem  
      {  
        public string Name { get; set; }  
        public int CompanyID { get; set; }  
      }  
    
      public class CompanyItem  
      {  
        public int ID { get; set; }  
        public string Name { get; set; }  
      }  
    
      public class ViewModel  
      {  
        public ViewModel()  
        {  
          GridItems = new ObservableCollection<GridItem>() {  
                new GridItem() { Name = "Jim", CompanyID = 1 } };  
    
          CompanyItems = new ObservableCollection<CompanyItem>() {  
                new CompanyItem() { ID = 1, Name = "Company 1" },  
                new CompanyItem() { ID = 2, Name = "Company 2" } };  
        }  
    
        public ObservableCollection<GridItem> GridItems { get; set; }  
        public ObservableCollection<CompanyItem> CompanyItems { get; set; }  
      }  
    }  
    

    The result:
    170867-4.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
     Note: Please follow the steps in our [documentation][5] to enable e-mail notifications if you want to receive the related email notification for this thread. 

    [5]: https://learn.microsoft.com/en-us/answers/articles/67444/email-notifications.html