Home > other >  Why are DataGrid items empty even if it is bound to an ObservableCollection that has rows in WPF?
Why are DataGrid items empty even if it is bound to an ObservableCollection that has rows in WPF?

Time:08-28

I'm using C# WPF

I have Datagrid that is filled by an observable collection named: "ALLTASKLIST" filled with Select data from a Database

I used DataBdinging to display data from "ALLTASKLIST" in my DataGrid

but it's empty!

XAML: <DataGrid.Columns>

            <DataGridComboBoxColumn Header="CMB">
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding Path=ALLTASKLIST}" />
                        <Setter Property="DisplayMemberPath" Value="NAMES" />
                        <Setter Property="SelectedValuePath" Value="CODE" />
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
        </DataGrid.Columns>

       
    </DataGrid> 

Code behind:

  public partial class MainWindow : Window
    {
        NEGIN1401Entities dbms = null;
        public class ThePart1 : INotifyPropertyChanged
        {
            private int? _CODE;
            private string _NAMES;
            private int? _KIND;
            private int? _idd;
            public int? CODE
            {
                get { return _CODE; }
                set
                {
                    _CODE = value;
                    OnPropertyChanged("CODE");
                }
            }
            public string NAMES
            {
                get { return _NAMES; }
                set
                {
                    _NAMES = value;
                    OnPropertyChanged("NAMES");
                }
            }
            public int? KIND
            {
                get { return _KIND; }
                set
                {
                    _KIND = value;
                    OnPropertyChanged("KIND");
                }
            }
            public int? idd
            {
                get { return _idd; }
                set
                {
                    _idd = value;
                    OnPropertyChanged("idd");
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
            public void OnPropertyChanged(string strCaller = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(strCaller));
            }
        }
        //public ObservableCollection<ThePart1> ALLTASKLIST { get; set; }
        public ObservableCollection<ThePart1> ALLTASKLIST = new ObservableCollection<ThePart1>();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            dbms = new NEGIN1401Entities(Publications.TheENTTConnectionString);

            ALLTASKLIST = dbms.Database.SqlQuery<ThePart1>("SELECT * FROM TCOD_ANBAR").ToObservableCollection();
            var IsHaveItems = ALLTASKLIST.Count;//it will be 6 Items
            //MainDatagrid.ItemsSource = ALLTASKLIST;

        }
    }

The Data Grid's items: enter image description here

Result: enter image description here

CodePudding user response:

  1. The binding path needs a property, not a field.
  2. Your style will set values for the ComboBox at the row level, and the data context will be the collection element ThePart1, not MainWindow. Accordingly, the binding path will be interpreted relative to ThePart1, which does not have the ALLTASKLIST property.
  3. A feature of the DataGridComboBoxColumn is that the source is obtained immediately when the DataGrid is created. Therefore, the source is usually created either in App resources or in a static property.

Try this example:

        public static ObservableCollection<ThePart1> ALLTASKLIST {get;}
            = new ObservableCollection<ThePart1>();
            ALLTASKLIST.Clear();
            for(var tp1 in dbms.Database.SqlQuery<ThePart1>("SELECT * FROM TCOD_ANBAR").ToList())
                ALLTASKLIST.Add(tp1);
    <DataGridComboBoxColumn Header="CMB"
                            ItemsSource="{x:Static local:MainWindow.ALLTASKLIST}">

CodePudding user response:

First of all you should bind to property, not field. Change it

 public ObservableCollection<ThePart1> ALLTASKLIST = new ObservableCollection<ThePart1>();

to this

public ObservableCollection<ThePart1> ALLTASKLIST { get; set; }

I think you have problems with DataContext of DataGrid. Try to set it to DataGrid directly within XAML by creating a local instance of MainWindow within XAML.(See EldHasp's question)

Also, try to set UpdateSourceTrigger property to PropertyChanged because maybe columns are updated but you can't simply see updates without focus. Set DataGrid's AutoGenerateColumns property to false, so it will not create new columns.

  • Related