locked
How to bind Combobox to a collection in Datagrid?? RRS feed

  • Question

  • I have grid , one of the column is combobox?? I have to bind this with one collection??

    Am not able to find control???

    Sunday, July 24, 2011 11:25 PM

Answers

  • if you want to bind the comboBox in code behind and are not using the MVVM pattren then here is what you have to replace , here is the xaml to replace the DataGridTemplateCell for the ComboBox xaml.

     <sdk:DataGridTemplateColumn Header="Gender">
                        <sdk:DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                <ComboBox Width="80" Height="25" Loaded="ComboBox_Loaded"></ComboBox>
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellEditingTemplate>
                    </sdk:DataGridTemplateColumn>

    and here is the loaded event handler for the ComboBox control.

        private void ComboBox_Loaded(object sender, RoutedEventArgs e)
            {
                ComboBox  senderComboBox = sender as ComboBox;
                senderComboBox.ItemsSource = GetListOfGenders;
                senderComboBox.SelectedItem = ((Customer)((DataGridCell)(senderComboBox.Parent)).DataContext).Gender;
     
            }

    and you can see that I have used the DataContext of the cell and bind the selectedItem of the comboBox. the List of gender is also in code behind as property which I have used in HomeViewModel in previous post.

    Monday, July 25, 2011 12:50 AM

All replies

  • Here are some of the useful links regarding your question

    Binding comboBox inside edit cell.

    http://social.msdn.microsoft.com/Forums/en-US/silverlightcontrols/thread/2395b6ae-e0af-4821-9189-6f9cc51c67df#d1fa0809-c7f7-43f7-bbd0-18093c63bd5f

     

    http://social.msdn.microsoft.com/Forums/en-US/silverlightdesigning/thread/722de750-634c-423a-8b94-242631c439e3#3370bcd0-bd65-4437-a420-d4156e036c9f

     

    Hope that will help. One question are you usnig MVVM, and the Collection which is used to bind the comboBox is within the viewModel or in the collection which is used to bind the datagird control

     

     

    Monday, July 25, 2011 12:03 AM
  • Here is technique to do it using MVVM, Here is my xaml

     <sdk:DataGrid  ItemsSource="{Binding Source={StaticResource homeVeiwModel},Path=Customers}" AutoGenerateColumns="False">
                <sdk:DataGrid.Columns>
                    <sdk:DataGridTextColumn Binding="{Binding FirstName}" Header="First Name"/>
                    <sdk:DataGridTextColumn Binding="{Binding LastName}" Header="Last Name"/>
                    <sdk:DataGridTemplateColumn Header="Gender">
                        <sdk:DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                <ComboBox Width="80" Height="25" 
                                          SelectedItem="{Binding Path=Gender,Mode=TwoWay}" ItemsSource="{Binding GetListOfGenders,Source={StaticResource genderList}}"></ComboBox>
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellEditingTemplate>
                    </sdk:DataGridTemplateColumn>
                </sdk:DataGrid.Columns>
            </sdk:DataGrid>

     

    and here is my viewModel class

      public class HomeViewModel : INotifyPropertyChanged
        {
            ObservableCollection<Customer> customers = new ObservableCollection<Customer>();
            public ObservableCollection<Customer> Customers
            {
                get { return customers; }
                set { customers = value;
                NotifyPropertyChanged("Customers");
                }
            } 
    
           
          
            #region " Default Constructor "
            /// <summary>
            /// 
            /// </summary>
            public HomeViewModel()
            {
                customers = new ObservableCollection<Customer>();
                customers.Add(new Customer() { FirstName = "Customer", LastName = " 01", Gender = "Male" });
                customers.Add(new Customer() { FirstName = "Customer", LastName = " 02", Gender = "Male" });
                customers.Add(new Customer() { FirstName = "Customer", LastName = " 03", Gender ="Female" });
                customers.Add(new Customer() { FirstName = "Customer", LastName = " 04" }); 
            }
            #endregion
    
            #region " INotifyPropertyChanged Interface "
    
            // Declare the PropertyChanged event
            public event PropertyChangedEventHandler PropertyChanged;
    
            // NotifyPropertyChanged will raise the PropertyChanged event passing the
            // source property that is being updated.
            public void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            #endregion
        }
    
        public class Customer
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string Gender { get; set; }
        }
    
        public class GenderList
        {
            public List<string> GetListOfGenders
            {
                get
                {
                    List<string> GenderList = new List<string>();
                    GenderList.Add("Male");
                    GenderList.Add("Female"); return GenderList;
                }
            }
        }

    Hope that will solve problem, You can also put the GetListOfGenders property of the GenderList in the HomeViewModel class and set the source of the binding of the comboBox to the homeViewModel which I have added as resource. 

    Monday, July 25, 2011 12:26 AM
  • if you want to bind the comboBox in code behind and are not using the MVVM pattren then here is what you have to replace , here is the xaml to replace the DataGridTemplateCell for the ComboBox xaml.

     <sdk:DataGridTemplateColumn Header="Gender">
                        <sdk:DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                <ComboBox Width="80" Height="25" Loaded="ComboBox_Loaded"></ComboBox>
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellEditingTemplate>
                    </sdk:DataGridTemplateColumn>

    and here is the loaded event handler for the ComboBox control.

        private void ComboBox_Loaded(object sender, RoutedEventArgs e)
            {
                ComboBox  senderComboBox = sender as ComboBox;
                senderComboBox.ItemsSource = GetListOfGenders;
                senderComboBox.SelectedItem = ((Customer)((DataGridCell)(senderComboBox.Parent)).DataContext).Gender;
     
            }

    and you can see that I have used the DataContext of the cell and bind the selectedItem of the comboBox. the List of gender is also in code behind as property which I have used in HomeViewModel in previous post.

    Monday, July 25, 2011 12:50 AM
  • Hi Asimsajjad,

    Thanks 4 ur reply. Few points to note::

    I am not using ViewModel. Its just a simple Collection that's is declared as Local resource in XAML. 

    My Collection is a class that inherits from Collectio<Object> class. At constructor level i am making async call to service. 

    so when actually local resource have values that varies. [I hope I am not confusing you.]

    Well I am waiting for more input's from your side.

    Thanks N regards,

    Monday, July 25, 2011 2:43 AM
  • Hi Asimsajjad,

    Thanks 4 ur reply. Few points to note::

    I am not using ViewModel. Its just a simple Collection that's is declared as Local resource in XAML. 

    My Collection is a class that inherits from Collectio<Object> class. At constructor level i am making async call to service. 

    so when actually local resource have values that varies. [I hope I am not confusing you.]

    Well I am waiting for more input's from your side.

    Thanks N regards,

    I am confuse by "At constructor level i am making async call to service" statement, please explain more about what is your requirement. what I have understand from you as you said that you are not using MVVM, then my second post will he helpful as you can see that all the binding is in the code behind. is your comboBox loaded event not fulfil your requirement ?

     

    Monday, July 25, 2011 2:48 AM
  • My Collection class :::

    public class FYCollection : Collection<object>
    {
    public FYCollection()
    {
    MyService.CommonServiceClient client = new MyService.CommonServiceClient();


    client.GetCalenderDetailCompleted += new EventHandler<CommonServices.GetCalenderDetailCompletedEventArgs>(client_GetCalenderDetailCompleted);
    client.GetCalenderDetailAsync();
    }

    void client_GetCalenderDetailCompleted(object sender, CommonServices.GetCalenderDetailCompletedEventArgs e)
    {
    ObservableCollection<CommonServices.Calendar> calendarItem = null;
    if (e.Error != null)
    {
    ErrorLogger.DisplayError(e.Error.Message.ToString());
    }
    else
    {

    if (e.Result != null && e.Result.Count > 0)
    {

    calendarItem = (ObservableCollection<CommonServices.Calendar>)e.Result;
    foreach (CommonServices.Calendar i in calendarItem)
    {
    string str = (i.FM + "-" + "FY" + "-" + i.FY);
    Add(str);
    }
    }
    else
    {
    if (App.SHOWERROR)
    {
    ErrorLogger.DisplayError("No Calendar Item found");
    }
    }
    }
    }
    }
    
    
    above is my collection class. to which I am binding my combobox inside grid.
      <UserControl.Resources>
    <local:FYCollection x:Name="FYColl"></local:FYCollection>
    </UserControl.Resources>
    above is my resource..
    
    
    <ComboBox x:Name="cmbMonth" Height="25"  ItemsSource="{Binding Source={StaticResource FYColl}}" SelectionChanged="cmbMonth_SelectionChanged" Loaded="cmbMonth_Loaded">
    </ComboBox>
    declaration of combobox insie grid...
    now loaded event executes before service call back methods executes... 
    and in loaded I am trying to set seletedIndex=0, so it is throwing error as data has not yet come to combobox(it is empty).
    
    
    I hope I am clear now... 
    Thanks once more...
    Monday, July 25, 2011 3:14 AM
  • You need to set the selectedIndex after you have assign source to the ComboBox.  or you can also bind the SelectedIndex by having property in FYCollection class. and when your data loaded then you can set the value for the selectedIndex as well.

    Monday, July 25, 2011 3:24 AM