One of our customers had an interesting requirement of using a Custom DropDown Editor in a C1FlexGrid column wherein the DropDown is a C1DropDownControl. One thing that makes this Editor different from the normally used editors for C1FlexGrid column(s) is that, here the DropDownForm used for the C1DropDownControl contains a C1FlexGrid Tree bound to C1DataSource (Entity Framework DataSource). This blog explains how one can implement the same. Also, we will discuss here that how to automatically open this dropdown when the user types in a character in the respective Column's cell & display only the matched records in the DropDown C1FlexGrid.

Binding the C1FlexGrid with C1DataSource (Entity Framework DataSource)

Firstly, we need to bind the main C1FlexGrid with the C1DataSource. For this, you can refer to here.

  • To one of the columns in the grid, assign the C1DropDownControl as a Editor for a grid's column.
  • Add a DropDownForm in your Application.

Customize the DropDownForm

In the DropDownForm, add a C1FlexGrid control. Bind this grid too with a C1DataSource object. We wish to have the DropDown show up as C1FlexGrid formatted Tree. For this, add the following piece of code in the Dropdown's Load event & grid's AfterDataRefresh event :


private void DropDownForm_Load(object sender, EventArgs e)  
{  
   SetUpGrid();  
}  

public void SetUpGrid()  
{  
    c1FlexGrid1.Tree.Column = 1;  
    c1FlexGrid1.Sort(SortFlags.Ascending, 1);  
    c1FlexGrid1.Subtotal(AggregateEnum.None, 0, 1, 1, "{0}");  
}  

private void c1FlexGrid1_AfterDataRefresh(object sender, ListChangedEventArgs e)  
{  
    c1FlexGrid1.Subtotal(AggregateEnum.None, 0, 1, 1, "{0}");  
}  

After the user selects a value from the DropDown C1FlexGrid, we need to assign that value to our main C1FlexGrid's cell, i.e., postback the changes to the main C1FlexGrid when a value is selected from the dropdown C1FlexGrid & close the dropdown :


private void c1FlexGrid1_BeforeMouseDown(object sender, BeforeMouseDownEventArgs e)  
{  
    if (c1FlexGrid1.HitTest(e.X, e.Y).Type == HitTestTypeEnum.Cell)  
    {  
        OwnerControl.Value = c1FlexGrid1[c1FlexGrid1.Row, "Title"].ToString();  
        CloseDropDown();  
    }  
}  

Lastly, we will assign this DropDownForm to the DropDownFormClassName property of C1DropDownControl. We now have something like this : CustomDropDownInFlex

Filter the Records in the DropDown C1FlexGrid

After a character is typed in the Main C1FlexGrid's column, where we have the Custom Editor, the dropdown should open up & the records in it should get autofilter :


private void c1FlexGrid1_KeyDown(object sender, KeyEventArgs e)  
{  
    if (c1FlexGrid1.Col == 4)  
    {  
         Keydwn = True  
         //Filter records before the DropDown is opened  
         ApplyFilter(sender, e.KeyData.ToString());  
    }  
}  
bool flag = false;  

private void c1FlexGrid1_KeyUpEdit(object sender, C1.Win.C1FlexGrid.KeyEditEventArgs e)  
{  
    if (Keydwn == true)  
    {  
       SendKeys.Send("{BACKSPACE}");  
       flag = true;  
    }  
    if (c1FlexGrid1.Col == 4)  
    {  
        if (e.KeyCode == Keys.Back)  
        {  
            flag = true;  
            C1.Win.Data.Entities.EntityViewSourceCollection vs = ((C1.Win.Data.Entities.C1DataSource)((C1.Win.C1FlexGrid.C1FlexGrid)this.c1DropDownControl1.DropDownForm.Controls[0]).DataSource).ViewSources;  
            vs[0].FilterDescriptors.Clear();  
        }  
        else  
        {  
            //Open the DropDown after a character is typed  
            c1DropDownControl1.OpenDropDown();  
            if (flag)  
                ApplyFilter(sender, e.KeyData.ToString());  
        }  
    }  
}  

private void c1FlexGrid1_SelChange(object sender, EventArgs e)  
{  
    if (c1FlexGrid1.Col == 4)  
    {  
        //If the Selected cell changes  
        //Clear all the previously set filter Descriptors  
        C1.Win.Data.Entities.EntityViewSourceCollection vs = ((C1.Win.Data.Entities.C1DataSource)((C1.Win.C1FlexGrid.C1FlexGrid)this.c1DropDownControl1.DropDownForm.Controls[0]).DataSource).ViewSources;  
        vs[0].FilterDescriptors.Clear();  
    }  
}  

//Apply Filtering in the ViewSource of the DropDown C1FlexGrid bound to C1DataSource  
private void ApplyFilter(object sender, string value)  
{  

    C1.Win.Data.Entities.EntityViewSourceCollection vs = ((C1.Win.Data.Entities.C1DataSource)((C1.Win.C1FlexGrid.C1FlexGrid)this.c1DropDownControl1.DropDownForm.Controls[0]).DataSource).ViewSources;  

    vs[0].FilterDescriptors.Clear();  

    //Create filterdescriptors to perform filtering in the ViewSource  
    C1.Data.DataSource.FilterDescriptor fd = new C1.Data.DataSource.FilterDescriptor();  

    //Column on which Filetring has to be applied  
    fd.PropertyPath = "Title";  
    //Records which are to be filtered  
    fd.Value = value;  

    fd.Operator = C1.Data.DataSource.FilterOperator.StartsWith;  
    vs[0].FilterDescriptors.Add(fd);  

}  

CustomDropDownEditorInFlex Download Sample VB Download Sample CS