My WPF DataGrid not displaying the Combobox

SupunDev 1 Reputation point
2021-10-03T12:44:34.033+00:00

Hi Everyone I'm trying to generate a combox column from code behind for my datagrid.

XAML

<DataGrid
                x:Name="ParaGrid"
                Margin="12,240,12,12"
                AutoGenerateColumns="True"
                BorderBrush="Black"
                BorderThickness="1"
                IsReadOnly="False" />

CodeBehind

DataGridComboBoxColumn styleList1 = new DataGridComboBoxColumn();
styleList1.Header = "Tags";            
styleList1.ItemsSource = StyleHandler.GetParaList.ToArray<object>();
styleList1.IsReadOnly = false;
ParaGrid.Columns.Add(styleList1);

I can see the header is generated but no Combobox. What is the reason for this?

Any help is very much appreciated. Thank you very much in advance

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,185 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
7,001 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
559 questions
No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Lloyd Sheen 781 Reputation points
    2021-10-03T15:20:29.54+00:00

    You have indicated that the DataGrid will create it's own columns. The header is simply the property name. All columns will be by default a DataGridTextColumn. If you want other column types you will need to generate your own columns in XAML for the DataGrid.


  2. Lloyd Sheen 781 Reputation points
    2021-10-03T21:40:52.177+00:00

    In the DataGridComboBoxColumn you need to indicate the collection that populates the ComboBox and the Selected item in the collection. I find that DataGridComboBoxColumn is difficult to work with. I would suggest a DataGridTemplateColumn with the CellTemplate a standard ComboBox with binding for the collection of items to choose from and the SelectedItem to get the selected item in the ComboBox.

    No comments

  3. Hui Liu-MSFT 14,721 Reputation points Microsoft Employee
    2021-10-04T06:24:29.56+00:00

    For binding the collection to the Combobox in the DataGrid, you could refer to the following example. When editing the last row of cells to add a new row in the DataGrid, what you can do is:

    1. Make sure your DataGrid has CanUserAddRows=True.
    2. Make sure the class in the collectiuon that you are binding has a default constructor (no parameters).
    3. Make sure the collection type is not readonly.

    For more information, you can refer here.

    The code of xaml:

    <Window.DataContext>  
            <local:ViewModel></local:ViewModel>  
        </Window.DataContext>  
        <Grid Background="AliceBlue" >  
            <DataGrid Name="dataGrid" ItemsSource="{Binding MyCollection}"  BorderBrush="Black"  
                    BorderThickness="1" AutoGenerateColumns="False"  CanUserAddRows="True" >  
                <DataGrid.Columns>  
                    <DataGridTextColumn Binding="{Binding Name}" Header="Name of person"/>  
                    <DataGridTemplateColumn Header="Age of person" >  
                        <DataGridTemplateColumn.CellTemplate>  
                            <DataTemplate>  
                                  
                                <ComboBox ItemsSource="{Binding Path=DataContext.Source1, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"  
                                  IsSynchronizedWithCurrentItem="False" IsHitTestVisible="False"  SelectedValue="{Binding Age}"  SelectedValuePath="Number"  DisplayMemberPath="Number"/>  
                            </DataTemplate>  
                        </DataGridTemplateColumn.CellTemplate>  
                        <DataGridTemplateColumn.CellEditingTemplate>  
                            <DataTemplate>  
                                <StackPanel>  
                                    <ComboBox ItemsSource="{Binding Path=DataContext.Source1, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"  
                                   SelectedValue="{Binding Age}"  SelectedValuePath="Number"  DisplayMemberPath="Number"  
                                              IsSynchronizedWithCurrentItem="False" IsEditable="True"/>  
                                </StackPanel>  
                            </DataTemplate>  
                        </DataGridTemplateColumn.CellEditingTemplate>  
                    </DataGridTemplateColumn>  
                    <DataGridTextColumn Binding="{Binding Salary}" Header="Persons salary"/>  
                </DataGrid.Columns>  
            </DataGrid>  
        </Grid>  
    

    The code of xaml.cs:

    using System.Windows;  
    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System;  
    using System.Windows.Controls;  
      
    namespace DataGridCombobox  
    {  
      public partial class MainWindow : Window  
      {  
        private bool _justCreatedNewItem;  
        public MainWindow()  
        {  
          InitializeComponent();  
          dataGrid.BeginningEdit += (o, e) =>  
          {  
            if (_justCreatedNewItem)  
            {  
              dataGrid.CommitEdit(DataGridEditingUnit.Row, true);  
              _justCreatedNewItem = false;  
            }  
          };  
          dataGrid.InitializingNewItem += (o, e) => { _justCreatedNewItem = true; };  
        }  
      }  
      public class ViewModel : INotifyPropertyChanged  
      {  
        public event PropertyChangedEventHandler PropertyChanged ;  
      
        private void NotifyPropertyChanged(String info)  
        {  
          if (PropertyChanged != null)  
          {  
            PropertyChanged(this, new PropertyChangedEventArgs(info));  
          }  
        }  
        private ObservableCollection<MyClass> _myCollection { get; set; }  
      
        public ObservableCollection<MyClass> MyCollection  
        {  
          get { return _myCollection; }  
          set  
          {  
            _myCollection = value;  
            NotifyPropertyChanged(nameof(MyCollection));  
          }  
        }  
        private ObservableCollection<Source1> _source1 { get; set; }  
        public ObservableCollection<Source1> Source1  
        {  
          get { return _source1; }  
          set { _source1 = value; NotifyPropertyChanged(nameof(Source1)); }  
        }  
        public ViewModel()  
        {  
          _source1 = new ObservableCollection<Source1>();  
          _myCollection = new ObservableCollection<MyClass>();  
          SetupSource();  
      
        }  
        private void SetupSource()  
        {  
          _source1.Add(new Source1(2));  
          _source1.Add(new Source1(3));  
          _source1.Add(new Source1(5));  
          _source1.Add(new Source1(8));  
          _myCollection.Add(new MyClass("name1",12,30.3));  
          _myCollection.Add(new MyClass("name2",22,30.3));  
          _myCollection.Add(new MyClass("name3",32,30.3));  
          _myCollection.Add(new MyClass("name3",32,30.3));  
        }  
      
      
      }  
      public class Source1  
      {  
        public int Number { get; set; }  
        public Source1(int n)  
        {  
          Number = n;  
        }  
      }  
      public class MyClass  
      {  
        public string Name { get; set; }  
        public int Age { get; set; }  
        public double Salary { get; set; }  
        public MyClass()  
        {  
      
        }  
        public MyClass(string n, int a, double s)  
        {  
          Name = n;  
          Age = a;  
          Salary = s;  
        }  
      }  
    }  
    

    The picture of result:
    137617-5.gif


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


  4. Lloyd Sheen 781 Reputation points
    2021-10-04T13:28:42.38+00:00

    Not about your problem in general but I would suggest if you are going to use WPF to learn XAML and data binding. When I switched from WinForms to WPF it was to "make a better looking app". I spent as you are doing lots of time trying to simulate what was happening in WinForms in WPF. This caused lots of problems as you have found and can be solved by using WPF in the WPF way.

    Learn MVVM and you will have the basis for solving most of your WPF problems.

    No comments