none
Accessing Combobox inside WPF Datagrid Template Column

    Pregunta

  • Hi,

    I am creating a WPF datagrid template column with combobox. The problem that I face now is, I am not able to bind a table to the combobox inside the WPF datagrid template column.

    Here is the code snippet.

    <dg:DataGrid x:Name="Students" AutoGenerateColumns="False" Loaded="OnLoad">
                <dg:DataGrid.Columns>
                  <dg:DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" Width="75"/>
                  <dg:DataGridTemplateColumn x:Name="Dept">
    							<dg:DataGridTemplateColumn.CellTemplate>
    								<DataTemplate>
    									<ComboBox x:Name="DeptId" ItemsSource="{Binding}"
    											SelectionChanged="Dept_SelectionChanged"
    											DisplayMemberPath="{Binding Path=DeptName}"
    											SelectedValuePath="{Binding Path=DeptId}"
    											SelectedItem="{Binding Path=Belongs}"/>
    								</DataTemplate>
    							</dg:DataGridTemplateColumn.CellTemplate>
    							</dg:DataGridTemplateColumn>
                </dg:DataGrid.Columns>
              </dg:DataGrid>
    
    

    Please help me to find out the way to assign a dynamic source to the combobox through code behind file.

    Thanks in Advance!!!

    Best Regards,
    Subalakshmi Vijayarajan.

    jueves, 02 de septiembre de 2010 10:21

Respuestas

  • Vimal,

    I found answer. The code is as below:

     

    <Page x:Class="ShutdownList"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
          xmlns:local="clr-namespace:WPFWindowsClient"
          Title="CreateUpdateShutdownList" Loaded="Page_Loaded" Unloaded="Page_Unloaded">
        <Page.Resources>
            <local:Priority x:Key="priorityProvider"/>
        </Page.Resources>

        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <DockPanel LastChildFill="True" Margin="0,50,0,0">
                <Label DockPanel.Dock="Bottom" Height="5"/>
                <dg:DataGrid Name="ShutdownTasksGridView" Background="Transparent"
                         AutoGenerateColumns="False" ItemsSource="{Binding}" CanUserAddRows="False"
                         CanUserDeleteRows="False" CanUserResizeRows="False"
                         PreviewKeyDown="ShutdownTasksGridView_PreviewKeyDown"
                         VirtualizingStackPanel.IsVirtualizing="False"
                         SelectionChanged="ShutdownTasksGridView_SelectionChanged">
                    <dg:DataGrid.BitmapEffect>
                        <OuterGlowBitmapEffect GlowColor="SteelBlue" />
                    </dg:DataGrid.BitmapEffect>
                    <dg:DataGrid.Columns>
                        <dg:DataGridTemplateColumn x:Name="Priority" Header="Priority">
                            <dg:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox DisplayMemberPath="Priority"
                                              SelectedValuePath="Priority"
                                              SelectedValue="{Binding Path=Priority}"
                                              Name="PriorityComboBox" SelectionChanged="PriorityComboBox_SelectionChanged"
                                              ItemsSource="{Binding PriorityList, Source={StaticResource priorityProvider}}" />
                                </DataTemplate>
                            </dg:DataGridTemplateColumn.CellTemplate>
                        </dg:DataGridTemplateColumn>
                    </dg:DataGrid.Columns>
                </dg:DataGrid>
            </DockPanel>
        </Grid>
    </Page>

    Backend coding

    namespace WPFWindowsClient
    {
        /// <summary>
        /// Class to return the priority list
        /// </summary>
        public class Priority
        {
            #region Variables
            //to store the priority list
            private DataTable dtPriorityList = new DataTable();
            #endregion

            /// <summary>
            /// Default constructor
            /// </summary>
            public Priority()
            {
                //create the table with the priority list
                dtPriorityList.Columns.Add("Priority");
                dtPriorityList.Rows.Add("High");
                dtPriorityList.Rows.Add("Medium");
                dtPriorityList.Rows.Add("Low");
            }

            /// <summary>
            /// Get the list of priority
            /// </summary>
            public DataTable PriorityList
            {
                get
                {
                    return dtPriorityList;
                }
            }
        }
    }

     

    Based on your initial replies, this worked for me Vimal.
    Thanks a lot for your efforts.

    Thanks & Regards,
    Subalakshmi Vijayarajan.

    martes, 07 de septiembre de 2010 12:03
  • Suba,

    Thanks for posting your code. Actually even i had this idea. But i was thinking that you may not create separate class. so i was trying to do something with code behind class. My solution also works if you just try to bind the data from the code behind file

    Anyway its nice to see that you found the solution. :-)

     

    regards,

    Vimal


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.
    martes, 07 de septiembre de 2010 13:15

Todas las respuestas

  • Hi,

    u need to use RelativeSource to Bind as its a part a datatemlate

     

     

    jueves, 02 de septiembre de 2010 10:36
  • can you help me this with code?

    Thanks & Regards,
    Subalakshmi Vijayarajan.

    jueves, 02 de septiembre de 2010 11:07
  • try out this link if u want it in codebehind

    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7cd30c60-9034-49f2-b401-48d4db1b9ba5

    and for XAML

    <DataTemplate>
    									<ComboBox x:Name="DeptId" ItemsSource="{Binding}"
    											SelectionChanged="Dept_SelectionChanged"
    											DisplayMemberPath="{Binding Path=DeptName}"
    											SelectedValuePath="{Binding Path=DeptId}"
    											SelectedItem="{Binding Path=Belongs}"/>
    								</DataTemplate>
    replace each binding with this example
    
    ItemsSource={Binding List,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ComboBox}}

    hope this willl help u

     

    jueves, 02 de septiembre de 2010 11:25
  • Hi,

    The xaml part is fine. But how do I need to bind the dynamically generated datatable to the combobox from the code behind file :(

    Thanks & Regards,
    Subalakshmi Vijayarajan.

    jueves, 02 de septiembre de 2010 11:38
  • Sorry.... It doesn't worked.... since we are not using any row details property..... :(

    Thanks and Regards,
    Subalakshmi Vijayarajan.

    jueves, 02 de septiembre de 2010 11:59
  • Hi Subalakshmi,

    Please try the below code, Hope it helps

    <dg:DataGrid x:Name="Students" AutoGenerateColumns="False" Loaded="OnLoad">

    <dg:DataGrid.Resources>

    <DataTemplate x:Key="dgDeptIdCombobox">
    <ComboBox x:Name="DeptId" ItemsSource="{Binding}"
    SelectionChanged="Dept_SelectionChanged"
    DisplayMemberPath="{Binding Path=DeptName}"
    SelectedValuePath="{Binding Path=DeptId}"
    SelectedItem="{Binding Path=Belongs, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
    </DataTemplate>

    </dg:DataGrid.Resources>

                <dg:DataGrid.Columns>
                  <dg:DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" Width="75"/>
                  <dg:DataGridTemplateColumn x:Name="Dept" Header="Dept" CellTemplate="{StaticResource dgDeptIdCombobox}">

           </dg:DataGridTemplateColumn>
                </dg:DataGrid.Columns>
              </dg:DataGrid>

    regards,

    Vimal


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.
    jueves, 02 de septiembre de 2010 12:00
  • Vimal,

    Thanks for your reply. Design is fine now. But how can I bind the datatable to the combobox through code behind file :(. Can you please give me the code snippet for that?

    Thanks & Regards,
    Subalakshmi Vijayarajan.

    jueves, 02 de septiembre de 2010 12:08
  • Suba,

    Please go through the following links to know about combobox binding through code behind....

    http://www.codeproject.com/KB/WPF/WPF.aspx

    http://www.ervinter.com/2008/09/08/wpf-combobox-data-binding/

     

    Still, if you have any doubts on this then feel free to let me know. :-)

    regards,

    Vimal

     


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.
    jueves, 02 de septiembre de 2010 18:08
  • Vimal,

    Thanks for your reply. I have already worked with code to bind datatable to combobox :). The problem I face now is I am not able to get the combobox name inside the DataTemplate to bind it to a datatable through code behind file. Hope you get my problem. Thanks for your efforts.

    Best Regards,
    Subalakshmi Vijayarajan.

    viernes, 03 de septiembre de 2010 3:59
  • Hi Suba,

    Please try the following code

    <dg:DataGrid x:Name="Students" AutoGenerateColumns="False" Loaded="OnLoad">

    <dg:DataGrid.Resources>

    <Style x:Key="comboBoxKey" TargetType="{x:Type ComboBox}">


    </dg:DataGrid.Resources>

                <dg:DataGrid.Columns>
                  <dg:DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" Width="75"/>
                  <dg:DataGridTemplateColumn x:Name="Dept" Header="Dept" >

    <dg:DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
    <ComboBox x:Name="DeptId" ItemsSource="{Binding Source={StaticResource comboBoxKey}}
    SelectionChanged="Dept_SelectionChanged"
    DisplayMemberPath="{Binding Path=DeptName}"
    SelectedValuePath="{Binding Path=DeptId}"
    SelectedItem="{Binding Path=Belongs, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
    </DataTemplate>

    </dg:DataGridTemplateColumn.CellTemplate>


           </dg:DataGridTemplateColumn>
                </dg:DataGrid.Columns>
              </dg:DataGrid>

     

    C#

               Style style = Students.FindResource("comboBoxKey") as Style;
               style.Setters.Add(new Setter(ComboBox.ItemsSourceProperty, _deptDataTable.DefaultView));

    Hope this works :-)

    But may i know why didn't use DataGridComboboxColumn?

    regards

    Vimal


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.
    viernes, 03 de septiembre de 2010 5:01
  • Hi Vimal,

    Datagridcombobox column is working fine, but if you try to select a value from the datagridcombobox column, it will first select the row, then the cell and finally open the dropdown list. Thus to select a value from the datagridcombobox column it needs three mouse clicks. If I need to do selection in more than 25 rows, this will become a tedious job. Hence, I am trying to use the datagrid template column with combobox.

    Hope you get my point.

    Thanks & Regards,
    Subalakshmi Vijayarajan.

    viernes, 03 de septiembre de 2010 5:13
  • Vimal,

    I believe the solution will work fine. But, which place you feel apt to write the source code that you have given? Do we need to write in Initialization of the controls?

    Thanks and Regards,
    Subalakshmi Vijayarajan.

    viernes, 03 de septiembre de 2010 5:28
  • You should write that code, once you fill the DataTable.

    Hope it works fine:-)

     


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.
    viernes, 03 de septiembre de 2010 5:39
  • Vimal,

    The code works fine but still the combobox is not filled with the table :-(

    Regards,
    Subalakshmi Vijayarajan.

    viernes, 03 de septiembre de 2010 5:51
  • Hi Subalakshmi Vijayarajan,

    How about the problem now? What do you mean that the combobox is not filled with the table. If you have any questions, please feel free to let me know.

    Best regards,
    Kevin Pan


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    lunes, 06 de septiembre de 2010 14:02
  • Hi Suba,

    Sorry for the late reply. Please try the following code

    <dg:DataGrid x:Name="Students" AutoGenerateColumns="False" Loaded="OnLoad">

    <dg:DataGrid.Resources>

    <Style x:Key="comboBoxKey" TargetType="{x:Type ComboBox}">


    </dg:DataGrid.Resources>

                <dg:DataGrid.Columns>
                  <dg:DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" Width="75"/>
                  <dg:DataGridTemplateColumn x:Name="Dept" Header="Dept" >

    <dg:DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
    <ComboBox x:Name="DeptId" Style="{StaticResource comboBoxKey}
    SelectionChanged="Dept_SelectionChanged"
    />
    </DataTemplate>

    </dg:DataGridTemplateColumn.CellTemplate>


           </dg:DataGridTemplateColumn>
                </dg:DataGrid.Columns>
              </dg:DataGrid>

     

    C#

               Style style = Students.FindResource("comboBoxKey") as Style;
               style.Setters.Add(new Setter(ComboBox.ItemsSourceProperty, _deptDataTable.DefaultView));

               style.Setters.Add(new Setter(ComboBox.DisplayMemberPath, "DeptName"));

               style.Setters.Add(new Setter(ComboBox.SelectedValuePath, "DeptId"));


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.
    • Propuesto como respuesta ksvimal martes, 07 de septiembre de 2010 13:16
    martes, 07 de septiembre de 2010 5:41
  • Vimal,

    I found answer. The code is as below:

     

    <Page x:Class="ShutdownList"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
          xmlns:local="clr-namespace:WPFWindowsClient"
          Title="CreateUpdateShutdownList" Loaded="Page_Loaded" Unloaded="Page_Unloaded">
        <Page.Resources>
            <local:Priority x:Key="priorityProvider"/>
        </Page.Resources>

        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <DockPanel LastChildFill="True" Margin="0,50,0,0">
                <Label DockPanel.Dock="Bottom" Height="5"/>
                <dg:DataGrid Name="ShutdownTasksGridView" Background="Transparent"
                         AutoGenerateColumns="False" ItemsSource="{Binding}" CanUserAddRows="False"
                         CanUserDeleteRows="False" CanUserResizeRows="False"
                         PreviewKeyDown="ShutdownTasksGridView_PreviewKeyDown"
                         VirtualizingStackPanel.IsVirtualizing="False"
                         SelectionChanged="ShutdownTasksGridView_SelectionChanged">
                    <dg:DataGrid.BitmapEffect>
                        <OuterGlowBitmapEffect GlowColor="SteelBlue" />
                    </dg:DataGrid.BitmapEffect>
                    <dg:DataGrid.Columns>
                        <dg:DataGridTemplateColumn x:Name="Priority" Header="Priority">
                            <dg:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox DisplayMemberPath="Priority"
                                              SelectedValuePath="Priority"
                                              SelectedValue="{Binding Path=Priority}"
                                              Name="PriorityComboBox" SelectionChanged="PriorityComboBox_SelectionChanged"
                                              ItemsSource="{Binding PriorityList, Source={StaticResource priorityProvider}}" />
                                </DataTemplate>
                            </dg:DataGridTemplateColumn.CellTemplate>
                        </dg:DataGridTemplateColumn>
                    </dg:DataGrid.Columns>
                </dg:DataGrid>
            </DockPanel>
        </Grid>
    </Page>

    Backend coding

    namespace WPFWindowsClient
    {
        /// <summary>
        /// Class to return the priority list
        /// </summary>
        public class Priority
        {
            #region Variables
            //to store the priority list
            private DataTable dtPriorityList = new DataTable();
            #endregion

            /// <summary>
            /// Default constructor
            /// </summary>
            public Priority()
            {
                //create the table with the priority list
                dtPriorityList.Columns.Add("Priority");
                dtPriorityList.Rows.Add("High");
                dtPriorityList.Rows.Add("Medium");
                dtPriorityList.Rows.Add("Low");
            }

            /// <summary>
            /// Get the list of priority
            /// </summary>
            public DataTable PriorityList
            {
                get
                {
                    return dtPriorityList;
                }
            }
        }
    }

     

    Based on your initial replies, this worked for me Vimal.
    Thanks a lot for your efforts.

    Thanks & Regards,
    Subalakshmi Vijayarajan.

    martes, 07 de septiembre de 2010 12:03
  • Suba,

    Thanks for posting your code. Actually even i had this idea. But i was thinking that you may not create separate class. so i was trying to do something with code behind class. My solution also works if you just try to bind the data from the code behind file

    Anyway its nice to see that you found the solution. :-)

     

    regards,

    Vimal


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.
    martes, 07 de septiembre de 2010 13:15
  • Thanks for your efforts too Vimal :)

    Regards,
    Subalakshmi Vijayarajan.

    miércoles, 08 de septiembre de 2010 7:01
  • Hi Suba, can you post the code on how to access the combobox(like selected priority here in this case) on event "PriorityComboBox_SelectionChanged"

    Thanks

    Mohan.

     

     

    miércoles, 08 de septiembre de 2010 19:39
  • Mohan,

    Sorry for the late reply. Here you are binding the combobox to the datagrid. Hence, when ever you change the selection in the priority combobox, it will affect the value in the priority column of that row where the priority combobox value changed.

    Hence, in selection changed code, I will get the value of the prioroty combobox as follows.

    private void PriorityComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
          try
          {
            //get the selected task id
            DataRowView selectedRow = (DataRowView)ShutdownTasksGridView.SelectedItem;
            if (selectedRow != null)
            {
              //get the selected priority
              string AssignedPriority = selectedRow.Row["Priority"].ToString();
            }
          }
          catch (Exception ex)
          {
            
          }
          finally
          {
            
          }
        }
    
    Hope it helps you. Let me know if it helped you.
    Best Regards,
    Subalakshmi Vijayarajan.
    lunes, 13 de septiembre de 2010 9:03
  • Thanks Suba, it works fine!

    Mohan.

     

    miércoles, 15 de septiembre de 2010 19:08
  • Hi Suba,

    I am a novice to WPF & have similar requirement in my application. I just applied the same logic as above in my app I am not sure how to define priorityProvider, resource declared in the page. If you can put more light on this part it'll be of great help to me. Kindly share your thought on the same.

    Thanks & Regards,
    Shweta. 

     

    jueves, 10 de febrero de 2011 10:06