简体   繁体   中英

Binding combobox to another combobox

I have a problem with binding combobox to another combobox. I'm trying to dynamically pass a parameter (id) from first combobox to the method of initiating second combobox. For example, if I selected the first item in first combobox, then second combobox will initialize with parameter that selected from first combobox.

XAML:

<ComboBox Name="ItServiceCmbox" ItemsSource="{Binding ItServiceMetricsNames}" DisplayMemberPath="ServiceName" SelectedValuePath="ServiceId" />
<ComboBox Name="MetricCmbox" ItemsSource="{Binding SelectedItem.MetricId, ElementName=ItServiceCmbox}" DisplayMemberPath="MetricName" SelectedValuePath="MetricId"/>

C#:

public partial class MainWindow : Window
{
    readonly MetricsValuesHelper _metricsValuesHelper = new MetricsValuesHelper(new Repository());
    public static int SelectedService;
    public static int SelectedMetric;
    public ObservableCollection<ItServiceMetricsNames> ItServiceMetricsNames { get; set; }      

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        SelectedService = Convert.ToInt32(ItServiceCmbox.SelectedItem);
        ItServiceMetricsNames = new ObservableCollection<ItServiceMetricsNames>();
        ItServiceMetricsNames.Add(new ItServiceMetricsNames()
        {
            ServiceId = _metricsValuesHelper.GetServiceId(),
            ServiceName = _metricsValuesHelper.GetServiceName(),
            MetricId = _metricsValuesHelper.GetMetricId(SelectedService),
            MetricName = _metricsValuesHelper.GetMetricName(SelectedService)
        });
    }
}

And ItServiceMetricsNames class:

public class ItServiceMetricsNames
{
    public List<int> ServiceId { get; set; }
    public List<string> ServiceName { get; set; }
    public List<int> MetricId { get; set; }
    public List<string> MetricName { get; set; }
}

Is it possible? Thanks for any answers!

This is a messy, naive implementation I did last year that seemed to work. There's definitely a better way out there. Instead of trying to do any actual binding in my xaml I made event handlers. You may create event handlers for ComboBoxes that are triggered whenever the sending ComboBox loses focus, closes it's DropDown, changes selection, etc.

If you want one ComboBox dependent on another, you may make the dependent ComboBox disabled until a selection is made in the independent ComboBox. Once a selection is made, you populate and enable the dependent ComboBox with the appropriate data.

Event handlers in your code will look something like this:

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // Independent ComboBox is the sender here
        ProcessComboBoxes(sender as ComboBox);
    }

The ProcessComboBoxes method will look different depending on what you're trying to do. But, essentially, it will identify the target/dependent ComboBox that you want to conditionally populate -- do this either with a Dictionary that maps from ComboBox to ComboBox or something you find suiting. After identifying the target, you will clear any items previously added, and then repopulate with your new ones. Below is a method in pseudocode (practically).

    private void ProcessComboBoxes(ComboBox senderBox)
    {
        ComboBox dependentBox = lookupDependent[senderBox];

        var itemType = itemTypes[senderBox.selectedIndex];
        var listOfItemsNeeded = lookupItemsByType[itemType];
        dependentBox.Items.Clear();

        foreach (string item in listOfItemsNeeded){
            dependentBox.Items.Add(item);
        }

        dependentBox.IsEnabled = true;
    }

Don't forget to add your eventhandlers to your xaml. Make sure to pay close attention to the call hierarchy of events and determine when exactly you want your dependent ComboBox to be repopulated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM