I'm using C# WPF with a SQL Server database. I have DataGrid that filled by Factor
table from database (ItemSource).
Inside of this DataGrid, I have a combobox that is also filled with different table as Commodity
that is related to Factor
.
What I need
I want the combobox I have to be filled with a list from my Commodity
table, but what is selected as the value is from the data grid (from the value filled in each row).
What have I tried
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"
x:Name="InvoiceWindow"
Title="MainWindow" Height="450" Width="800" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded">
<Grid>
<DataGrid x:Name="MainDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding WHOLE_DATA_FACTOR, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="Customer Name" Width="120" Binding="{Binding CustomerName, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<DataGridTemplateColumn Header="The Product Customer Bought" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox_Commodity"
ItemsSource="{Binding ElementName=InvoiceWindow ,Path=TheCommodityCombo_DATA}"
DisplayMemberPath="CommodityName"
SelectedValuePath="CommodityCode"
IsTextSearchEnabled="True"
IsEditable="True"
SelectedIndex="0" BorderBrush="#FFADEEB4" Background="{x:Null}" BorderThickness="1">
<!--For ComboBox_Commodity ↑-->
<!--SelectedValue="{Binding The selected value of each combo box is proportional and based on the value of that row in the datagrid}"-->
<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:
public partial class MainWindow : Window
{
MyerEntities dbms = new MyerEntities();
/// <summary>
/// For Factor Table
/// </summary>
public class MyCustomModel_Factor
{
public long? NUMBER { get; set; }
public string CustomerName { get; set; }
public long? CommodityCode { get; set; }
}
public ObservableCollection<MyCustomModel_Factor> WHOLE_DATA_FACTOR { get; set; } = new ObservableCollection<MyCustomModel_Factor>();
/// <summary>
/// For Commodity Table for ComboBox Items
/// </summary>
public ObservableCollection<MyCustomModel_Commodity> TheCommodityCombo_DATA { get; set; } = new ObservableCollection<MyCustomModel_Commodity>();
public class MyCustomModel_Commodity
{
public long CommodityCode { get; set; }
public string CommodityName { get; set; }
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Filling DataGrid by ObservableCollection
WHOLE_DATA_FACTOR.Clear();
var RST = dbms.Database.SqlQuery<MyCustomModel_Factor>("SELECT * FROM Factor").ToList();
foreach (var item in RST)
{ WHOLE_DATA_FACTOR.Add(item); }
//Filling ComboBox from another table that is related to Factor table
TheCommodityCombo_DATA.Clear();
var RST2 = dbms.Database.SqlQuery<MyCustomModel_Commodity>("SELECT CommodityCode, CommodityName FROM dbo.Commodity").ToList();
foreach (var item2 in RST2)
{
TheCommodityCombo_DATA.Add(item2);
}
}
}
My source code: https://ufile.io/x4xqe9ti
Similar question but for Winforms: How do I show the display value for a combo box for the bound item?
How can I do that in WPF? Please help
CodePudding user response:
Change the binding to the collection of commodities to use a RelativeSource
:
ItemsSource="{Binding Path=TheCommodityCombo_DATA, RelativeSource={RelativeSource AncestorType=Window}}"
Then you should see the values to choose from in the ComboBox
.
For the correct value to get selected, you should then bind the SelectedValue
property of the ComboBox
to the CommodityCode
property of the model:
<ComboBox ... SelectedValue="{Binding CommodityCode}"