This is a migrated thread and some comments may be shown as answers.

GridViewComboBoxColumns link

11 Answers 123 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Ludovic Gerbault
Top achievements
Rank 1
Ludovic Gerbault asked on 31 Aug 2009, 08:02 AM
Hi

In my scenario, I have 2 GridViewComboBoxColumns.

In ComboBox A, I have a fixed itemsource : idA - textA
In ComboBoxB, I have another itemsource : idB - textB - idA

What I'd like to do is to filter the itemsource of combobox B according to the selectedItem of comboBox A, filtering that would occur on the idA.

Of course, each time I change the value in combobox A, an event would be fired to change the itemsource of comboBox B.

Do you know of a way to perform such a thing ?

11 Answers, 1 is accepted

Sort by
0
Ludovic Gerbault
Top achievements
Rank 1
answered on 02 Sep 2009, 09:40 AM
I could really use some help on that issue, please ?
0
Pavel Pavlov
Telerik team
answered on 03 Sep 2009, 08:37 AM
Hello Subileau Pascal,
Please have a look at the attached sample application.

I have tried to illustrate an implementation of scenario similar to yours.

There are two ComboBox columns in the RadGridView - one for selecting a continent and the next one for selecting a country.
When the user enters a continent , the country combobox will update and will contain countries from the selected continent.

In case you have troubles adapting this to your project or such approach is not applicable for you , just let me know .

Best wishes,
Pavel Pavlov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Ludovic Gerbault
Top achievements
Rank 1
answered on 03 Sep 2009, 09:41 AM
Thanks, but it is not the kind of approach I can use.

I'm gonna try to detail my scenario

1 - My XAML is very simple, there it is :

<telerikGrid:RadGridView x:Class="SilverClient.FormGrid" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:telerikGrid="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView" 
    Width="Auto" Height="300" x:Name="FormGrille"  CanUserInsertRows="True" 
    ShowGroupPanel="False" ColumnsWidthMode="Fill" AutoGenerateColumns="False" 
    AddingNewDataItem="FormGrille_AddingNewDataItem" RowEditEnded="FormGrille_RowEditEnded" 
    CellEditEnded="FormGrille_CellEditEnded" BeginningEdit="FormGrille_BeginningEdit" 
    KeyDown="FormGrille_KeyDown"
 
</telerikGrid:RadGridView> 
 

2 - I query my database to get a list of fields that I use to create a dynamic form. Some of this field can by typed as "Grid"
When I have a Grid type, I add a column in my grid, the resultset I retreive from the database tells me what kind of column it is (combobox, string, decimal, date...)
If it is a comboBox type, the resultset also contains the itemsource of the comboBox in a form of a string, that I convert into a DataTable with 2 columns : "id" and "name"

So for instance, I can have 2 comboBoxColumns, the first is a type of account (with two items "Customer" and "Provider") and the second is the account (with several items, both of Customer and Provider type)

What I want to do is that when I select the item customer, I want the second combobox to only display the accounts related to customer type.

I would have done it long ago if there was a SelectionChanged event in the GridViewComboBox column, but I couldn't find such event. I would have query my database again, for example, and reset the combobox itemsource.

My grid isn't attached to a specified class, that would give it any kind of structure with propertychanged event, it is bind to a DataTable (the one I found in one of the telerik's admin blog), I use dynamic binding using the header name of the column and the column name of the table.

I hope this description would help you understand my scenario and help me figure this thing out.
0
Pavel Pavlov
Telerik team
answered on 03 Sep 2009, 12:12 PM

Hi Subileau Pascal,
Thanks for sharing the details.

So what we are looking for is a way to react to combobox selection changes. I thing there is a way to handle these.

Here is how:
The selection changed event of RadComboBox ( the default editor for ComboBoxColumn) is a routed event , so you can subscribe the following way:

this.AddHandler(RadComboBox.SelectionChangedEvent, new RoutedEventHandler(this.OnComboSelectionChanged), true); 

* Be sure to add  using Telerik.Windows;  or else you will get a compile error trying this line of code.

Now the event handler should look something like :

 

void OnComboSelectionChanged(object sender, RoutedEventArgs args)  
        {  
            Telerik.Windows.Controls.SelectionChangedEventArgs e = args as Telerik.Windows.Controls.SelectionChangedEventArgs;  
            RadComboBox sourceComboBox = ((Telerik.Windows.Controls.SelectionChangedEventArgs) args).Source as RadComboBox;  
            Object relatedDataBaseItem = sourceComboBox.DataContext;  
        } 

Please note that this event handler is called for any comboboxes in the grid ( including the ones in the filtering ui). That is why you should check the DataContext of the source combo . When the user interacts with your combo , the DataContext will be your database item.
The code above illustrates how to get the Combobox and the related database item .

I have tried this code here and it seems to work fine . In case you need further assistance , just let me know.

Regards,

Pavel Pavlov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Ludovic Gerbault
Top achievements
Rank 1
answered on 03 Sep 2009, 12:45 PM
Thanks for the sode snippet, this is very helpful.

I've tried it out, and I can now fire the event on the selection change of my combos (filtering is not a problem, I'm blocking that functionnality) but it seems that the value that is being returned by the ComboBox is the old selected value, not the new one.

The DataContext variable also seems to be empty, I don't know why.

Any thoughts ?
0
Ludovic Gerbault
Top achievements
Rank 1
answered on 03 Sep 2009, 12:47 PM
To be precise, the debbugger says "Could not evaluate expression"
0
Ludovic Gerbault
Top achievements
Rank 1
answered on 03 Sep 2009, 12:50 PM
Maybe it'd be easier for anyone if you had the code I'm working on

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Linq; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 
using Telerik.Windows; 
using Telerik.Windows.Controls; 
using Telerik.Windows.Data; 
using Telerik.Windows.Controls.GridView; 
using SilverClient.SilverClientService; 
using System.Windows.Data; 
namespace SilverClient 
    public partial class FormGrid : UserControl 
    { 
        ClientSilverClient _wsSilverClient = new ClientSilverClient(); 
        ObservableCollection<GridControl> collection = new ObservableCollection<GridControl>(); 
        DataTable structure = new DataTable(); 
        public FormGrid(int id_societe,int id_categorie,int id_contact,string nom_conteneur) 
        { 
            InitializeComponent(); 
            this.AddHandler(RadComboBox.SelectionChangedEvent, new RoutedEventHandler(this.OnComboSelectionChanged), true); 
            _wsSilverClient.getInterfaceGrilleAsync(id_societe, id_categorie, id_contact, 0,nom_conteneur); 
            _wsSilverClient.getInterfaceGrilleCompleted += new EventHandler<getInterfaceGrilleCompletedEventArgs>(_wsSilverClient_getInterfaceGrilleCompleted); 
        } 
 
        void _wsSilverClient_getInterfaceGrilleCompleted(object sender, getInterfaceGrilleCompletedEventArgs e) 
        { 
            IList<InterfaceBO> result = e.Result; 
            int i=0; 
             
            DataRow row2 = new DataRow(); 
            foreach (InterfaceBO r in result) 
            {         
                switch (r.type_zone) 
                { 
                    case 1: GridViewDataColumn col; 
                            switch (r.id_format_param) 
                            { 
                                case 1: col = new GridViewDataColumn() { Header = r.lib_zone.Replace(' ','_'), DataType = typeof(string), DataMemberBinding = new Binding(r.lib_zone.Replace(' ', '_')) }; 
                                    structure.Columns.Add(new DataColumn() { ColumnName = r.lib_zone.Replace(' ', '_'), DataType = typeof(string) }); 
                                    row2[r.lib_zone.Replace(' ', '_')] = ""
                                    FormGrille.Columns.Add(col);  
                                    break
                                case 2: col = new GridViewDataColumn() { Header = r.lib_zone.Replace(' ', '_'), DataType = typeof(int), DataMemberBinding = new Binding(r.lib_zone.Replace(' ', '_')) }; 
                                    structure.Columns.Add(new DataColumn() { ColumnName = r.lib_zone.Replace(' ', '_'), DataType = typeof(int) }); 
                                    row2[r.lib_zone.Replace(' ', '_')] = 0; 
                                    FormGrille.Columns.Add(col);  
                                    break
                                case 3: col = new GridViewDataColumn() { Header = r.lib_zone.Replace(' ', '_'), DataType = typeof(decimal), DataMemberBinding = new Binding(r.lib_zone.Replace(' ', '_')), DataFormatString = "{0:F}", TextAlignment = TextAlignment.Right }; 
                                    structure.Columns.Add(new DataColumn() { ColumnName = r.lib_zone.Replace(' ', '_'), DataType = typeof(decimal) }); 
                                    row2[r.lib_zone.Replace(' ', '_')] = Convert.ToDecimal(0); 
                                    if (r.grille.Contains("Ecriture")) 
                                    {                                                                              
                                        SumFunction countFunction = new SumFunction(); 
                                        countFunction.ResultFormatString = "{0:F}"
                                        countFunction.SourceField = r.lib_zone; 
                                        countFunction.Caption = "Total : "
                                        col.AggregateFunctions.Add(countFunction); 
                                     
                                        FormGrille.ShowColumnFooters = true
                                        col.Footer = FormGrille.AggregateResults["countFunction"] ; 
 
                                    }  
                                    FormGrille.Columns.Add(col); 
                                    break
                                case 4: col = new GridViewDataColumn() { Header = r.lib_zone.Replace(' ', '_'), DataType = typeof(DateTime), DataMemberBinding = new Binding(r.lib_zone.Replace(' ', '_')) }; 
                                    structure.Columns.Add(new DataColumn() { ColumnName = r.lib_zone.Replace(' ', '_'), DataType = typeof(DateTime) }); 
                                    row2[r.lib_zone.Replace(' ', '_')] = DateTime.Now; 
                                    FormGrille.Columns.Add(col);  
                                    break
                                case 5: col = new GridViewDataColumn() { Header = r.lib_zone.Replace(' ', '_'), DataType = typeof(Boolean), DataMemberBinding = new Binding(r.lib_zone.Replace(' ', '_')) }; 
                                    structure.Columns.Add(new DataColumn() { ColumnName = r.lib_zone.Replace(' ', '_'), DataType = typeof(Boolean) }); 
                                    row2[r.lib_zone.Replace(' ', '_')] = false
                                    FormGrille.Columns.Add(col);  
                                    break;                                
                            }                        
 
                        break
                    case 2: break
                    case 3: GridViewComboBoxColumn col2 = new GridViewComboBoxColumn() { Header = r.lib_zone.Replace(' ', '_'), DataType = typeof(string), DataMemberBinding = new Binding(r.lib_zone.Replace(' ', '_')) }; 
                         
                        structure.Columns.Add(new DataColumn() { ColumnName = r.lib_zone.Replace(' ', '_'), DataType = typeof(string) }); 
                        row2[r.lib_zone.Replace(' ', '_')] = ""
                        FormGrille.Columns.Add(col2); 
                        String[] ComboValeurs = r.combo_lib.Split('|'); 
                         
                        DataTable table = new DataTable(); 
                        table.Columns.Add(new DataColumn() { ColumnName = "ID", DataType = typeof(string) }); 
                        table.Columns.Add(new DataColumn() { ColumnName = "Name", DataType = typeof(string) }); 
 
                        foreach (String r2 in ComboValeurs) 
                        { 
                            String[] temp = r2.Split('_'); 
                            if (temp[0] != ""
                            { 
                                DataRow row = new DataRow(); 
                                row["ID"] = temp[0].ToString(); 
                                row["Name"] = temp[1].ToString(); 
                                table.Rows.Add(row); 
                            } 
                            else 
                            { 
                                DataRow row = new DataRow(); 
                                row["ID"] = ""
                                row["Name"] = "aucun"
                                table.Rows.Add(row); 
                            } 
                        } 
 
                        col2.ItemsSource = table; 
                        col2.DisplayMemberPath = "Name"
                        col2.SelectedValueMemberPath = "ID"
                         
                        break
                    case 4: GridViewDataColumn col3 = new GridViewDataColumn() { Header = r.lib_zone.Replace(' ', '_'), DataType = typeof(bool), DataMemberBinding = new Binding(r.lib_zone.Replace(' ', '_')) }; 
                        structure.Columns.Add(new DataColumn() { ColumnName = r.lib_zone.Replace(' ', '_'), DataType = typeof(string) }); 
                        row2[r.lib_zone.Replace(' ', '_')] = false
                        FormGrille.Columns.Add(col3); 
                        break
                    case 5: break
                    case 6: GridViewDataColumn col4 = new GridViewDataColumn() { Header = r.lib_zone.Replace(' ', '_'), DataType = typeof(DateTime), DataMemberBinding = new Binding(r.lib_zone.Replace(' ', '_')) }; 
                         
                        FormGrille.Columns.Add(col4); 
                        structure.Columns.Add(new DataColumn() { ColumnName = r.lib_zone.Replace(' ', '_'), DataType = typeof(string) });  
                        row2[r.lib_zone.Replace(' ', '_')] = DateTime.Now; 
                        break
                    case 7: break
                } 
                 
                i++; 
            } 
 
            structure.Rows.Add(row2); 
            FormGrille.ItemsSource = structure; 
        } 
 
        void OnComboSelectionChanged(object sender, RoutedEventArgs args) 
        { 
            Telerik.Windows.Controls.SelectionChangedEventArgs e = args as Telerik.Windows.Controls.SelectionChangedEventArgs; 
            RadComboBox sourceComboBox = ((Telerik.Windows.Controls.SelectionChangedEventArgs)args).Source as RadComboBox; 
            Object relatedDataBaseItem = sourceComboBox.DataContext; 
        } 
 
        private void FormGrille_AddingNewDataItem(object sender, Telerik.Windows.Controls.GridView.GridViewAddingNewEventArgs e) 
        { 
            DataRow row = new DataRow(); 
            for (int i = 0; i < structure.Columns.Count; i++) 
            { 
                if (structure.Columns[i].DataType == typeof(string)) 
                { 
                    row.Add(structure.Columns[i].ColumnName, ""); 
                } 
                if (structure.Columns[i].DataType == typeof(decimal)) 
                { 
                    row.Add(structure.Columns[i].ColumnName, Convert.ToDecimal(0)); 
                } 
            } 
            structure.Rows.Add(row); 
            e.NewObject= row; 
             
        } 
 
        private void FormGrille_RowEditEnded(object sender, GridViewRowEditEndedEventArgs e) 
        { 
            /*
            foreach (GridViewCell cell in e.Row.Cells)
            {
                newData.Add(cell.Column.Header.ToString().Replace(' ','_'), cell.Content);
            }
            
            FormGrille.Rebind();*/ 
        } 
 
        private void FormGrille_CellEditEnded(object sender, GridViewCellEditEndedEventArgs e) 
        { 
            decimal output; 
            int index = FormGrille.Items.IndexOf(e.Cell.ParentRow.DataItem); 
            if (e.EditingElement.GetType() == typeof(RadComboBox)) 
            { 
                structure.Rows[index][e.Cell.Column.Header.ToString().Replace(' ', '_')] = ((RadComboBox)e.EditingElement).SelectedValue; 
            } 
            else 
            { 
                if (((GridViewDataColumn)e.Cell.Column).DataType == typeof(String)) 
                { 
                    structure.Rows[index][e.Cell.Column.Header.ToString().Replace(' ', '_')] = e.Cell.Content.ToString(); 
                } 
                if (((GridViewDataColumn)e.Cell.Column).DataType == typeof(int)) 
                { 
                    structure.Rows[index][e.Cell.Column.Header.ToString().Replace(' ', '_')] = Convert.ToInt32(e.Cell.Content); 
                } 
                if (((GridViewDataColumn)e.Cell.Column).DataType == typeof(decimal)) 
                { 
                    structure.Rows[index][e.Cell.Column.Header.ToString().Replace(' ', '_')] = Convert.ToDecimal(e.Cell.Content); 
                } 
                if (((GridViewDataColumn)e.Cell.Column).DataType == typeof(Boolean)) 
                { 
                    structure.Rows[index][e.Cell.Column.Header.ToString().Replace(' ', '_')] = Convert.ToBoolean(e.Cell.Content); 
                } 
                if (((GridViewDataColumn)e.Cell.Column).DataType == typeof(DateTime)) 
                { 
                    structure.Rows[index][e.Cell.Column.Header.ToString().Replace(' ', '_')] = Convert.ToDateTime(e.Cell.Content); 
                } 
           } 
       } 
 
        private void FormGrille_BeginningEdit(object sender, GridViewBeginningEditRoutedEventArgs e) 
        { 
 
        } 
 
        public DataTable GetDataGrille() 
        { 
            return structure; 
        } 
 
        private void FormGrille_KeyDown(object sender, KeyEventArgs e) 
        { 
             
        } 
 
        private void Button_Click(object sender, RoutedEventArgs e) 
        { 
            DataRow row = new DataRow(); 
            for (int i = 0; i < structure.Columns.Count; i++) 
            { 
                if (structure.Columns[i].DataType == typeof(string)) 
                { 
                    row.Add(structure.Columns[i].ColumnName, ""); 
                } 
                if (structure.Columns[i].DataType == typeof(decimal)) 
                { 
                    row.Add(structure.Columns[i].ColumnName, Convert.ToDecimal(0)); 
                }                 
            } 
            structure.Rows.Add(row);             
            FormGrille.Rebind(); 
        } 
    } 
 

0
Ludovic Gerbault
Top achievements
Rank 1
answered on 07 Sep 2009, 10:44 AM
Any further info on this matter ?
0
Pavel Pavlov
Telerik team
answered on 07 Sep 2009, 01:54 PM
Hi Subileau Pascal,

I am trying to reproduce the problem here. It would be very helpful if you open a support ticket and send me your project ( or a smaller project that resembles the issue ) .

The problem may come from incorrect settings of the GridViewComboBox column ( e.g. DisplayMemeberPath, SelectedValuePath or DataMemberBinding ). However this is just a guess.
As soon as I can reproduce the issue here I will  provide  a working solution.

Regards,
Pavel Pavlov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Ludovic Gerbault
Top achievements
Rank 1
answered on 07 Sep 2009, 02:46 PM
Actually, I almost found my way around this problem, using a specific class and
a very mcgyver kind IList<List<comboClass>> comboValues = new List<List<comboClaa>>();

My last problem to get it work as I want is to identify the column in which the radcomboBox was changed.

I'm using this code:

void OnComboSelectionChanged(object sender, RoutedEventArgs args)   
        {   
            Telerik.Windows.Controls.SelectionChangedEventArgs e = args as Telerik.Windows.Controls.SelectionChangedEventArgs;   
            RadComboBox sourceComboBox = ((Telerik.Windows.Controls.SelectionChangedEventArgs) args).Source as RadComboBox;   
            int relatedDataBaseItem = Convert.ToInt32(sourceComboBox.SelectedValue);   
        }  

If inside, there was a way to know the index of the column that holds the RadComboBox, I'll be done with this problem.

Hope you know a trick to perform this.


0
Ludovic Gerbault
Top achievements
Rank 1
answered on 07 Sep 2009, 05:07 PM
Don't bother.

I've used the currentItem property to managed to do what I need.

Dynamically changing the itemsource property between each row and keep the data was kind of hard to manage, but I've one it as well.

Anyway, thanks for your help.


Tags
GridView
Asked by
Ludovic Gerbault
Top achievements
Rank 1
Answers by
Ludovic Gerbault
Top achievements
Rank 1
Pavel Pavlov
Telerik team
Share this question
or