Cascading combobox
Hello,
I am trying to create a cascading combobox where the selection of the first combobox provides a filtered but searchable list in the second combobox.
The first combobox lists JobName and the second combobox lists JobTaskName. The job tasks need to be filtered by the JobNo selected in the job list. Ideally the user would then be able to search the filtered list without tasks from other jobs being shown.
I have tried filtering using the example here under custom filtering
Filtering in .NET MAUI ComboBox control | Syncfusion
But this errors with the sfCombobox not containing a definition for the ItemsSourceList.
source.ItemsSourceList.OfType Some code snippets of what I have so far is shown below.
Do you have a downloadable example? Any assistance would be most appreciated.
Regards
Ross
Cascading Combobox
Job
private ObservableCollection<Job> jobs;
public ObservableCollection<Job> Jobs
{
get { return jobs; }
set { jobs = value; OnPropertyChanged(nameof(Jobs)); }
}
Jobs = new ObservableCollection<Job>
{
new Job() { JobNo = "373", JobName = "373 - Whitford Quarry Final Faces" },
new Job() { JobNo = "380", JobName = "380 - Pokeno Miscellaneous 2017" },
new Job() { JobNo = "400", JobName = "400 - HLC Mangere West Stage 1" },
new Job() { JobNo = "440", JobName = "440 - Paerata Rise Stage 8 Civil" },
new Job() { JobNo = "441", JobName = "441 - Phoenix Property 20 Swanson Road" }
}
Job Task
public ObservableCollection<JobTask>
jobTasks;
public ObservableCollection<JobTask>
JobTasks
{
get { return jobTasks; }
set { jobTasks = value; OnPropertyChanged(nameof(JobTasks)); }
}
JobTasks = new ObservableCollection<JobTask>
{
new JobTask() { JobNo = "373", JobTaskNo = "010", JobTaskName = "010 - Preliminary & General" },
new JobTask() { JobNo = "373", JobTaskNo = "015", JobTaskName = "015 - Traffic Management" },
new JobTask() { JobNo = "373", JobTaskNo = "020", JobTaskName = "020 - Clearing & Demolition" },
new JobTask() { JobNo = "373", JobTaskNo = "030", JobTaskName = "030 - Sediment & Erosion Control" },
new JobTask() { JobNo = "373", JobTaskNo = "040", JobTaskName = "040 - Earthworks" },
new JobTask() { JobNo = "373", JobTaskNo = "045", JobTaskName = "045 - Geotech" },
new JobTask() { JobNo = "373", JobTaskNo = "050", JobTaskName = "050 - Drainage" },
new JobTask() { JobNo = "373", JobTaskNo = "060", JobTaskName = "060 - Roading" },
new JobTask() { JobNo = "373", JobTaskNo = "070", JobTaskName = "070 - Services" },
new JobTask() { JobNo = "373", JobTaskNo = "080", JobTaskName = "080 - Concrete" },
new JobTask() { JobNo = "373", JobTaskNo = "090", JobTaskName = "090 - Structures" },
new JobTask() { JobNo = "373", JobTaskNo = "100", JobTaskName = "100 - Variations" },
new JobTask() { JobNo = "373", JobTaskNo = "105", JobTaskName = "105 - Labour" },
new JobTask() { JobNo = "373", JobTaskNo = "110", JobTaskName = "110 - Plant" },
new JobTask() { JobNo = "373", JobTaskNo = "120", JobTaskName = "120 - Unproductive Work" },
new JobTask() { JobNo = "373", JobTaskNo = "140", JobTaskName = "140 - Remedial Work" },
new JobTask() { JobNo = "373", JobTaskNo = "WET", JobTaskName = "WET - Wet Weather" },
new JobTask() { JobNo = "380", JobTaskNo = "010", JobTaskName = "010 - Preliminary & General" },
new JobTask() { JobNo = "380", JobTaskNo = "015", JobTaskName = "015 - Traffic Management" },
new JobTask() { JobNo = "380", JobTaskNo = "020", JobTaskName = "020 - Clearing & Demolition" },
new JobTask() { JobNo = "380", JobTaskNo = "030", JobTaskName = "030 - Sediment & Erosion Control" },
new JobTask() { JobNo = "380", JobTaskNo = "040", JobTaskName = "040 - Earthworks" },
new JobTask() { JobNo = "380", JobTaskNo = "045", JobTaskName = "045 - Geotech" },
new JobTask() { JobNo = "380", JobTaskNo = "050", JobTaskName = "050 - Drainage" },
new JobTask() { JobNo = "380", JobTaskNo = "060", JobTaskName = "060 - Roading" },
new JobTask() { JobNo = "380", JobTaskNo = "070", JobTaskName = "070 - Services" },
new JobTask() { JobNo = "380", JobTaskNo = "080", JobTaskName = "080 - Concrete" },
new JobTask() { JobNo = "380", JobTaskNo = "090", JobTaskName = "090 - Structures" },
new JobTask() { JobNo = "380", JobTaskNo = "100", JobTaskName = "100 - Variations" },
new JobTask() { JobNo = "380", JobTaskNo = "105", JobTaskName = "105 - Labour" },
new JobTask() { JobNo = "380", JobTaskNo = "110", JobTaskName = "110 - Plant" },
new JobTask() { JobNo = "380", JobTaskNo = "120", JobTaskName = "120 - Unproductive Work" },
new JobTask() { JobNo = "380", JobTaskNo = "140", JobTaskName = "140 - Remedial Work" },
new JobTask() { JobNo = "380", JobTaskNo = "150", JobTaskName = "150 - Retentions" },
new JobTask() { JobNo = "380", JobTaskNo = "900", JobTaskName = "900 - Wet Weather" },
new JobTask() { JobNo = "400", JobTaskNo = "010", JobTaskName = "010 - Preliminary & General" },
new JobTask() { JobNo = "400", JobTaskNo = "015", JobTaskName = "015 - Traffic Management" },
new JobTask() { JobNo = "400", JobTaskNo = "020", JobTaskName = "020 - Clearing & Demolition" },
new JobTask() { JobNo = "400", JobTaskNo = "030", JobTaskName = "030 - Sediment & Erosion Control" },
new JobTask() { JobNo = "400", JobTaskNo = "040", JobTaskName = "040 - Earthworks" },
new JobTask() { JobNo = "400", JobTaskNo = "045", JobTaskName = "045 - Geotech" },
new JobTask() { JobNo = "400", JobTaskNo = "050", JobTaskName = "050 - Drainage" },
new JobTask() { JobNo = "400", JobTaskNo = "060", JobTaskName = "060 - Roading" },
new JobTask() { JobNo = "400", JobTaskNo = "070", JobTaskName = "070 - Services" },
new JobTask() { JobNo = "400", JobTaskNo = "080", JobTaskName = "080 - Streetscape Works" },
new JobTask() { JobNo = "400", JobTaskNo = "090", JobTaskName = "090 - Structures" },
new JobTask() { JobNo = "400", JobTaskNo = "100", JobTaskName = "100 - Variations" },
new JobTask() { JobNo = "400", JobTaskNo = "105", JobTaskName = "105 - Labour" },
new JobTask() { JobNo = "400", JobTaskNo = "110", JobTaskName = "110 - Plant" },
new JobTask() { JobNo = "400", JobTaskNo = "120", JobTaskName = "120 - Unproductive Work" },
new JobTask() { JobNo = "400", JobTaskNo = "140", JobTaskName = "140 - Remedial Work" },
new JobTask() { JobNo = "400", JobTaskNo = "WET", JobTaskName = "WET - 900 Wet Weather" },
new JobTask() { JobNo = "440", JobTaskNo = "010", JobTaskName = "010 - Preliminary & General" },
new JobTask() { JobNo = "440", JobTaskNo = "015", JobTaskName = "015 - Traffic Management" },
new JobTask() { JobNo = "440", JobTaskNo = "020", JobTaskName = "020 - Clearing & Demolition" },
new JobTask() { JobNo = "440", JobTaskNo = "030", JobTaskName = "030 - Sediment & Erosion Control" },
new JobTask() { JobNo = "440", JobTaskNo = "040", JobTaskName = "040 - Earthworks" },
new JobTask() { JobNo = "440", JobTaskNo = "045", JobTaskName = "045 - Geotech" },
new JobTask() { JobNo = "440", JobTaskNo = "050", JobTaskName = "050 - Drainage" },
new JobTask() { JobNo = "440", JobTaskNo = "060", JobTaskName = "060 - Roading" },
new JobTask() { JobNo = "440", JobTaskNo = "070", JobTaskName = "070 - Services" },
new JobTask() { JobNo = "440", JobTaskNo = "080", JobTaskName = "080 - Concrete" },
new JobTask() { JobNo = "440", JobTaskNo = "090", JobTaskName = "090 - Structures" },
new JobTask() { JobNo = "440", JobTaskNo = "100", JobTaskName = "100 - Variations" },
new JobTask() { JobNo = "440", JobTaskNo = "120", JobTaskName = "120 - Unproductive Work" },
new JobTask() { JobNo = "440", JobTaskNo = "140", JobTaskName = "140 - Remedial Work" },
new JobTask() { JobNo = "440", JobTaskNo = "WET", JobTaskName = "WET - 900 Wet Weather" },
new JobTask() { JobNo = "441", JobTaskNo = "010", JobTaskName = "010 - Preliminary & General" },
new JobTask() { JobNo = "441", JobTaskNo = "015", JobTaskName = "015 - Traffic Management" },
new JobTask() { JobNo = "441", JobTaskNo = "020", JobTaskName = "020 - Clearing & Demolition" },
new JobTask() { JobNo = "441", JobTaskNo = "030", JobTaskName = "030 - Sediment & Erosion Control" },
new JobTask() { JobNo = "441", JobTaskNo = "040", JobTaskName = "040 - Earthworks" },
new JobTask() { JobNo = "441", JobTaskNo = "045", JobTaskName = "045 - Geotech" },
new JobTask() { JobNo = "441", JobTaskNo = "050", JobTaskName = "050 - Drainage" },
new JobTask() { JobNo = "441", JobTaskNo = "060", JobTaskName = "060 - Roading" },
new JobTask() { JobNo = "441", JobTaskNo = "070", JobTaskName = "070 - Services" },
new JobTask() { JobNo = "441", JobTaskNo = "080", JobTaskName = "080 - Concrete" },
new JobTask() { JobNo = "441", JobTaskNo = "090", JobTaskName = "090 - Structures" },
new JobTask() { JobNo = "441", JobTaskNo = "100", JobTaskName = "100 - Variations" },
new JobTask() { JobNo = "441", JobTaskNo = "120", JobTaskName = "120 - Unproductive Work" },
new JobTask() { JobNo = "441", JobTaskNo = "140", JobTaskName = "140 - Remedial Work" },
new JobTask() { JobNo = "441", JobTaskNo = "150", JobTaskName = "150 - Retentions" },
new JobTask() { JobNo = "441", JobTaskNo = "900", JobTaskName = "900 - Wet Weather" }
}
private void OncboJobChanged(object sender, Syncfusion.Maui.Inputs.SelectionChangedEventArgs e)
{
if (cboJobs.SelectedItem == null) return;
getJobName = (cboJobs.SelectedItem as Job).JobName.ToString();
getJobNo = (cboJobs.SelectedItem as Job).JobNo.ToString();
getcboJobIndex = cboJobs.SelectedIndex;
getlinetype = 0;
}
xaml
<editors:SfComboBox
x:Name="cboJobs"
Grid.Row="2"
Grid.ColumnSpan="3"
ItemsSource="{Binding Jobs}"
DisplayMemberPath="JobName"
TextMemberPath="JobName"
SelectionChanged="OncboJobChanged"
SelectedValuePath="JobName"
Placeholder="Select a job"
TextSearchMode="Contains"
IsEditable="true"
IsFilteringEnabled="true"
/>
<editors:SfComboBox
x:Name="cboJobTasks"
Grid.Row="4"
Grid.ColumnSpan="3"
MaxDropDownHeight="500"
ItemsSource="{Binding JobTasks}"
DisplayMemberPath="JobTaskName"
SelectionChanged="OncboJobTaskChanged"
SelectedValuePath="JobTaskName"
Placeholder="Select a task"
TextSearchMode="Contains"
IsEditable="true"
IsFilteringEnabled="true">
<editors:SfComboBox.FilterBehavior>
<local:JobTaskFilteringBehavior/>
</editors:SfComboBox.FilterBehavior>
/>
public class JobTaskFilteringBehavior : IComboBoxFilterBehavior
{
public List<int> GetMatchingIndexes(SfComboBox source, ComboBoxFilterInfo filterInfo)
{
List<int> filteredlist = new List<int>();
List<JobTask> TaskItems = source.ItemsSourceList.OfType<JobTask>().ToList();
filteredlist.AddRange(from JobTask item in TaskItems
where item.JobNo.StartsWith(filterInfo.Text, StringComparison.CurrentCultureIgnoreCase)
select JobTask.IndexOf(item));
return filteredlist;
}
}
Hi Ross,
Thank you for your patience.
We have validated the reported query, Based on the provided details and code snippet we have developed the sample to meet your requirements. In the sample, when a JobName is selected from the first ComboBox, it filters the JobTaskName in the second ComboBox based on the JobNo in the collection.
Please review the sample provided and let us know if it fulfills your requirements. If you have any additional questions or concerns, don't hesitate to reach out.
Regards,
Kamalesh P
Attachment: ComboBoxSample_4fc492a5.zip
Thanks so much for this Kamalesh - awesome support as always. I will take a look and see if your example solves my problem.
Hi Ross Bell Syer,
You're welcome. Please test if the provided example works for you and let us know. We will wait to hear further updates from you.
Regards,
Preethi R
- 3 Replies
- 3 Participants
-
RB Ross Bell Syer
- Mar 3, 2024 04:49 AM UTC
- Mar 7, 2024 06:04 AM UTC