I want to Display data in my ComboBox inside of DataGridTemplateColumn
in the DataGrid
but it's empty in the binding so I decided to fill it in code behind but I couldn't access it by name!
XAML:
<Window x:Class="ComboDataWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ComboDataWPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded">
<Grid>
<DataGrid x:Name="MainDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="The Name :" Width="120" Binding="{Binding NAMES, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<DataGridTemplateColumn Header=" Name and Code " Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox1"
ItemsSource="{Binding ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
SelectedValuePath="{Binding CODE, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
DisplayMemberPath="{Binding NAMES, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
IsTextSearchEnabled="True"
IsEditable="True"
SelectedIndex="0" BorderBrush="#FFADEEB4" Background="{x:Null}" BorderThickness="1">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Code Behind:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ComboDataWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
MyerEntities dbms = new MyerEntities();
public ObservableCollection<MyCustomModel> ALLMYDATA { get; set; } = new ObservableCollection<MyCustomModel>();
public class MyCustomModel
{
public int CODE { get; set; }
public string NAMES { get; set; }
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ALLMYDATA.Clear();
var RST = dbms.Database.SqlQuery<MyCustomModel>("SELECT CODE,NAMES FROM TCOD_ANBAR").ToList();
foreach (var item in RST)
{
ALLMYDATA.Add(item);
}
}
}
}
my source: https://ufile.io/zvfoj4we
NOTE:
I even tried to switch to GridView
but it was harder than Datagrid.
so Why the ComboBox is empty and how can I access the property like ItemsSource and ... in C#?
Please guide me
I downloaded your source project. And filled ALLMYDATA collection with 2 objects(cuz I don't have DB for it).
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ALLMYDATA.Clear();
MyCustomModel myCustom = new MyCustomModel()
{
CODE = 20,
NAMES = "Yes"
};
MyCustomModel myCustom2 = new MyCustomModel()
{
CODE = 30,
NAMES = "No"
};
ALLMYDATA.Add(myCustom);
ALLMYDATA.Add(myCustom2);
}
So the main problems I saw were in your XAML. As you set DataGrid
's ItemsSource
property to ALLMYDATA
collection, it is DataContext
for all child elements of DataGrid
, and when you try to bind ComboBox
's ItemsSource
to property like
ItemsSource="{Binding ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
you get the error because DataContext
for ComboBox
is the ALLMYDATA collection and this collection doesn't contain the ALLMYDATA property, that's why you can't bind to it in ComboBox
. So I changed XAML code above to
ItemsSource="{Binding ElementName=MainDataGrid, Path=ItemsSource}"
and it works well as ItemsSource
of ComboBox
is the same as DataGrid
now.
Other problems are related to these pieces of code:
SelectedValuePath="{Binding CODE, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
DisplayMemberPath="{Binding NAMES, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
As your ComboBox
's ItemsSource
is ALLMYDATA, now you don't need to bind anything just write
SelectedValuePath="CODE"
DisplayMemberPath="NAMES"
Now your ComboBox
is not empty:
Here is the full XAML of your DataGrid
<DataGrid x:Name="MainDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding ALLMYDATA, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="The Name :" Width="120" Binding="{Binding NAMES, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<DataGridTemplateColumn Header=" Name and Code " Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox1"
ItemsSource="{Binding ElementName=MainDataGrid, Path=ItemsSource}"
SelectedValuePath="CODE"
DisplayMemberPath="NAMES"
IsTextSearchEnabled="True"
IsEditable="True"
SelectedIndex="0" BorderBrush="#FFADEEB4" Background="{x:Null}" BorderThickness="1">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>