How to Make a Generic SelectedItem for all ComboBo

2019-09-21 08:30发布

问题:

I'm new to WPF.

I'm trying to make the SelectedItem for all the comboboxes to generic as there are a lot of ComboBox in my form.

When I use different SelectedItem for each ComboBox it works fine.

C# Code:

private DropDownModel _mySelectedItem_DeviceType;
    public DropDownModel MySelectedItem_DeviceType
    {
        get { return _mySelectedItem_DeviceType; }
        set
        {
            if (_mySelectedItem_DeviceType != value)
            {
                _mySelectedItem_DeviceType = value;

                OnNotifyPropertyChanged("MySelectedItem_DeviceType");
            }
        }
    }
 private DropDownModel _mySelectedItem_All;
    public DropDownModel MySelectedItem_All
    {
        get { return _mySelectedItem_All; }
        set
        {
            if (_mySelectedItem_All != value)
            {
                _mySelectedItem_All = value;

                OnNotifyPropertyChanged("MySelectedItem_All");
            }
        }
    }

    private DropDownModel _mySelectedItem_Status;
    public DropDownModel MySelectedItem_Status
    {
        get { return _mySelectedItem_Status; }
        set
        {
            if (_mySelectedItem_Status != value)
            {
                _mySelectedItem_Status = value;

                OnNotifyPropertyChanged("MySelectedItem_Status");
            }
        }
    }
public event PropertyChangedEventHandler PropertyChanged;

    private void OnNotifyPropertyChanged(string propertyName)
    {
        var propertyChangedEvent = PropertyChanged;  

        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    } 
var myListDropDown = (from b in _entities.DeviceTypes
                                  select new DropDownModel
                                  {
                                      ID = b.ID,
                                      Name = b.Name
                                  }).Distinct().ToList();
            myListDropDown.Add(new DropDownModel
            {
                ID = -1,
                Name = "Select Device"
            });
            myListDropDown = myListDropDown.OrderBy(x => x.Name).ToList();

            //DisplayDeviceType = new ObservableCollection<DropDownModel>(myListDropDown);
            DisplayDeviceType = new ObservableCollection<DropDownModel>(myListDropDown);

            MySelectedItem_DeviceType = (from b in myListDropDown
                                               where b.ID == (singleDevice == null ? -1 : singleDevice.DeviceTypeID)
                                               select b).FirstOrDefault();
var allStatus = (from b in _entities.DeviceStatuses
                               select new DropDownModel
                               {
                                   ID = b.ID,
                                   Name = b.Status
                               }).Distinct().ToList();
            allStatus.Add(new DropDownModel
            {
                ID = -1,
                Name = "Select Status"
            });
            allStatus = allStatus.OrderBy(x => x.Name).ToList();

            Status = new ObservableCollection<DropDownModel>(allStatus);

            MySelectedItem_Status = (from b in allStatus
                                  where b.ID == (singleDevice == null ? -1 : singleDevice.StatusID)
                                  select b).FirstOrDefault();

XAML:

 <ComboBox Name="DeviceTypeComboBox"
                              Grid.Column="1"
                              HorizontalAlignment="Left"
                              VerticalAlignment="Top"
                              Width="143.917"
                              Grid.Row="1"
                              ItemsSource="{Binding DisplayDeviceType}"
                              SelectedItem="{Binding MySelectedItem_DeviceType}"
                              SelectedValue="ID"
                              SelectedValuePath="ID"
                              DisplayMemberPath="Name"

                              />
<ComboBox Name="StatusTypeComboBox"
                              HorizontalAlignment="Left"
                              VerticalAlignment="Top"
                              Width="143.917"
                              Grid.Column="4"
                              Grid.Row="1"
                              ItemsSource="{Binding Status}"
                              SelectedItem="{Binding MySelectedItem_Status}"
                              SelectedValue="ID"
                              SelectedValuePath="ID"
                              DisplayMemberPath="Name"
                              />

// Works Fine

But when I try to replace MySelectedItem_Status & MySelectedItem_DeviceType with MySelectedItem_All in my XAML. It throws an Exception.

Thanks,

回答1:

It sounds like you need to abstract a bit more and have a class that wraps up all these properties you are trying to set through combo box selected item.

For example

public class DeviceInfo
{
  private DeviceDisplayType deviceType;
  public DeviceDisplayType DeviceType
  {
    get { return deviceType; }
    set { deviceType = value; }
  }

  private DeviceStatus deviceStatus
  public DeviceStatus DeviceStatus
  {
    get { return deviceStatus; }
    set { deviceStatus = value; }
  }
}

And then have one of these DeviceInfo objects in your viewmodel, and make the xaml bind to those properties directly.

<ComboBox SelectedItem={Binding MyDeviceInfo.DeviceType} />

You will still need the properties somewhere, but rather than a disparate range of VM properties you are recognising that those properties are all part of a larger cohesive class.