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:
- The binding path needs a property, not a field.
- 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.
- 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.