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.
Firstly, we need to bind the main C1FlexGrid with the C1DataSource. For this, you can refer to here.
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 :
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);
}