I'm not going to write our code for you, but, I hope I can give you some ideas:
1 to fill the ComboBox with a set of nom duplicate items:
var cval = dt.AsEnumerable().Select(row => row[c2]).Distinct().Select(rw => rw.ToString()).ToList();
comboBox1.DataSource = cval;
2 filling the CheckdListBox when the ComboBox selection changes:
private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
{
checkedListBox1.Items.Clear();
string csel = comboBox1.SelectedValue.ToString();
foreach(DataRow row in dt.Rows)
{
if (row[2] == csel)
{
checkedListBox1.Items.Add($"{row[1]}\t\tMax Tons: {row[3]}");
}
}
}
Here, I made a choice to append the max tons to the string displayed in the CheckedListBox.
3 At this point we come to your goal to filter the CheckedListBoxItems by minimum and maximum capacity values. I suggest you use NumericUpDown Controls for user input.
It's too bad that CheckedListBoxItems do not have a 'Tag property you could stick the max capacity in. I suggest you create a reference Dictionary to map the ComboBoxItems to the combination of (perhaps a Tuple ?) of CraneModel and max capacity: then, when the user changes the capacity, min, or max, you can iterate this Dictionary to rebuild/update the CheckedListBoxItems,
// sketch Dictionary<comboboxitem, list<(?,="" ?.capacity)="">
Does the end-user really need to enter both min and max ?