question

BabuR-5260 avatar image
0 Votes"
BabuR-5260 asked AlexLi-MSFT answered

how to define source for wpf datagrid xaml DataGridComboBoxColumn

Hai
I am trying to set source for datagrid custom control DataGridComboBoxColumn.
I used code like this

In viewmodel

      public ObservableCollection<MarKList> NameList { get; set; }
    
  public ViewModel()
         {
             NameList =new ObservableCollection<MarKList>(db.MarKLists.ToList());
         }

in mainwindow

             private void Button_Click(object sender, RoutedEventArgs e)
             {
                 ViewModel VM = new ViewModel();
                 SubPage Sp = new SubPage();
                 Sp.DataContext = VM;
                 MainFrame.Content = Sp;
             }

and in page

 <local:DataGridUser x:Name="Dg_Student" ItemsSource="{Binding Vm_StudentCollection}"  CurrentItem="{Binding Vm_StudentCollection_Curitem,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"     AutoGenerateColumns="False"  HorizontalAlignment="Left" Height="282" Margin="107,58,0,0" VerticalAlignment="Top" Width="247" SelectionUnit="CellOrRowHeader" SelectionMode="Single">
 <local:DataGridUser.Columns>
                     <DataGridTextColumn Header="Name" Binding="{Binding M_Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"  />
                     <DataGridComboBoxColumn  Header="Gender"  ItemsSource="{Binding NameList}" DisplayMemberPath="Name" SelectedItemBinding="{Binding M_Enm_Gender_SelItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  SelectedValuePath="{Binding M_GenderID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="120">
                         <DataGridComboBoxColumn.ElementStyle>
                               <Style TargetType="{x:Type ComboBox}">
                              <Setter Property="ItemsSource" Value="{Binding Path=DataContext.NameList, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                            </Style>
                         </DataGridComboBoxColumn.ElementStyle>
                         <DataGridComboBoxColumn.EditingElementStyle>
                             <Style TargetType="{x:Type ComboBox}">
                             <Setter Property="ItemsSource" Value="{Binding Path=DataContext.NameList, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                           <Setter Property="IsEditable" Value="True"/>
                             </Style>
                         </DataGridComboBoxColumn.EditingElementStyle>
                     </DataGridComboBoxColumn>
                     <DataGridTextColumn Header="Mark1" Binding="{Binding M_Mark1, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
                     <DataGridTextColumn Header="Total" Binding="{Binding M_Total, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"  />
                 </local:DataGridUser.Columns>

I want to pollute name field from NameList to combo, I tried different methods but none worked. please help what I am doing wrong.
Also I don't want template column.

Thanks





windows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AlexLi-MSFT avatar image
0 Votes"
AlexLi-MSFT answered

Welcome to our Microsoft Q&A platform!

I use the below method to bind the data in the Page.xaml, the DataGridComboBoxColumn can show the namelist.

  1. Add the CollectionViewSource for the page


      <Page.Resources>
                     <CollectionViewSource x:Key="ItemsCVS" Source="{Binding NameList }" />
             </Page.Resources>
    

2.replace the your ItemsSource="{Binding NameList}" as ItemsSource="{Binding Source={StaticResource ItemsCVS}}" in DataGridComboBoxColumn

Thanks.



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered

Hi, the documentation on MSDN about the ItemsSource of the DataGridComboBoxColumn says that only static resources, static code or inline collections of combobox items can be bound to the ItemsSource. In your case you can use StaticResource in your XAML:

 <Page x:Class="WpfApp37.SubPage"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
       xmlns:local="clr-namespace:WpfApp37"
       mc:Ignorable="d" 
       d:DesignHeight="450" d:DesignWidth="800"
       Title="SubPage">
   <Page.Resources>
     <CollectionViewSource x:Key="GenderList" Source="{Binding NameList}" />
   </Page.Resources>
   <Grid x:Name="grd">
     <local:DataGridUser x:Name="Dg_Student" 
                         ItemsSource="{Binding Vm_StudentCollection}"  
                         CurrentItem="{Binding Vm_StudentCollection_Curitem,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"  
                         AutoGenerateColumns="False"
                         HorizontalAlignment="Left"
                         Height="282"
                         Margin="107,58,0,0" 
                         VerticalAlignment="Top" 
                         Width="247" 
                         SelectionUnit="CellOrRowHeader"
                         SelectionMode="Single">
       <local:DataGridUser.Columns>
         <DataGridTextColumn Header="Name" 
                             Binding="{Binding M_Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"  />
         <DataGridComboBoxColumn Header="Gender"  
                                 ItemsSource="{Binding Source={StaticResource GenderList}}"
                                 DisplayMemberPath="Name" 
                                 SelectedValuePath="ID"
                                 SelectedValueBinding="{Binding M_GenderID}">
         </DataGridComboBoxColumn>
         <DataGridTextColumn Header="Mark1" 
                             Binding="{Binding M_Mark1, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
         <DataGridTextColumn Header="Total" 
                             Binding="{Binding M_Total, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"  />
       </local:DataGridUser.Columns>
     </local:DataGridUser>
   </Grid>
 </Page>

You can test with following code:

 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
 using System.Windows;
 using WpfApp37;
    
 namespace WpfApp1
 {
   public partial class Window37 : Window
   {
     public Window37()
     {
       InitializeComponent();
     }
     private void Button_Click(object sender, RoutedEventArgs e)
     {
       ViewModel VM = new ViewModel();
       SubPage Sp = new SubPage();
       Sp.DataContext = VM;
       MainFrame.Content = Sp;
     }
   }
 }
    
 namespace WpfApp37
 {
   public class ViewModel
   {
     public ViewModel()
     {
       NameList = new ObservableCollection<MarKList>(db.MarKLists.ToList());
       Vm_StudentCollection = new ObservableCollection<Student>(db.StudentList.ToList());
     }  
     Model db = new Model();
     public ObservableCollection<MarKList> NameList { get; set; }
     public ObservableCollection<Student> Vm_StudentCollection { get; set; }
     public object Vm_StudentCollection_Curitem { get; set; }
   }
    
   public class Student
   {
     public string M_Name { get; set; }
     public int M_GenderID { get; set; }
     public string M_Mark1 { get; set; }
     public int M_Total { get; set; }
   }
    
   public class MarKList
   {
     public string Name { get; set; }
     public int ID { get; set; }
   }
    
   internal class Model
   {
     Random rnd = new Random();
     internal IEnumerable<MarKList> MarKLists
     {
       get
       {
         var l = new List<MarKList>();
         l.Add(new MarKList() { ID = 1, Name = "Male" });
         l.Add(new MarKList() { ID = 2, Name = "Female" });
         l.Add(new MarKList() { ID = 3, Name = "TransGender" });
         return l;
       }
     }
     internal IEnumerable<Student> StudentList { get { for (int i = 0; i < 10; i++) yield return new Student() { M_Name = $"Name {i}", M_GenderID = rnd.Next(1, 4), M_Mark1 = $"Mark1 {i}", M_Total = i }; } }
   }
 }

XAML of MainWindow:

 <Window x:Class="WpfApp1.Window37"
         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:WpfApp1"
         mc:Ignorable="d"
         Title="Window37" Height="450" Width="1000">
   <Grid>
     <Grid.RowDefinitions>
       <RowDefinition Height="Auto"/>
       <RowDefinition/>
     </Grid.RowDefinitions>
     <Frame x:Name="MainFrame"
            Grid.Row="1"/>
     <Button Content="Load Page" 
             Width="100" 
             Margin="5" 
             Click="Button_Click"/>
   </Grid>
 </Window>


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.