简体   繁体   English

在 WPF mvvm 中将项目添加到 ComboBox

[英]Add item to ComboBox in WPF mvvm

I'm dealing with a ComboBox in WPF and MVVM but I can't find how to populate the ComboBox in real time.我正在处理 WPF 和 MVVM 中的 ComboBox,但我找不到如何实时填充 ComboBox。

private ObservableCollection<AudioListaDevice> _audiodevicesitem = new ObservableCollection<AudioListaDevice>{
//Adding my first Item to test it
        new AudioListaDevice { AudioDeviceItem = "Test 01"},
        new AudioListaDevice { AudioDeviceItem = "Test 02"},
};
        public IEnumerable<AudioListaDevice> AudioDevicesItem { get { return _audiodevicesitem; } }
        private AudioListaDevice _AudioDevice;
        public AudioListaDevice AudioDevice
        {
            get
            { return _AudioDevice; }
            set
            {
                _AudioDevice = value; OnPropertyChanged("AudioDevice");
                //On Selection 
                Debug.WriteLine(_AudioDevice.AudioDeviceItem.ToString());
            }
        }

This is the class这是班级

public class AudioListaDevice : INotifyPropertyChanged
    {
        private string _AudioDeviceItem;
        public string AudioDeviceItem
        {
            get { return _AudioDeviceItem; }
            set { _AudioDeviceItem = value; OnPropertyChanged("AudioDeviceItem"); }
        }

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }

What I'm trying to do is add a new item in the collection later on from anywhere and refresh the ComboBox.我想要做的是稍后从任何地方在集合中添加一个新项目并刷新 ComboBox。

public MainWindowVM() 
        {
            _audiodevicesitem.Add(new AudioListaDevice("Test03"));

//not relevant code continues here...
}

This is the Xaml Binding这是 Xaml 绑定

<ComboBox x:Name="listaoutputdevices" 
          ItemsSource="{Binding AudioDevicesItem}"
          DisplayMemberPath="AudioDeviceItem"
          SelectedItem="{Binding AudioDevice}" 
          Grid.Row="0" Grid.Column="0" Margin="60,5,0,5" HorizontalAlignment="Left"  Width="352" >

The error says I don't have a contructor with an argument to pass the String via AudioListaDevice, but If I declare it in the Class AudioListaDevice : INotifyPropertyChanged错误说我没有带参数的构造函数来通过 AudioListaDevice 传递字符串,但是如果我在类 AudioListaDevice 中声明它:INotifyPropertyChanged

    private string item;
    public AudioListaDevice(string item)
        {
            this.item = item;
        }

Then然后

private ObservableCollection<AudioListaDevice> _audiodevicesitem = new ObservableCollection<AudioListaDevice>{
//Adding my first Item to test it
        new AudioListaDevice { AudioDeviceItem = "Test 01"},
        new AudioListaDevice { AudioDeviceItem = "Test 02"},
};

Gives an error when adding the previous items and the ComboBox doesn't reflect the添加以前的项目时出错,并且 ComboBox 不反映

_audiodevicesitem.Add(new AudioListaDevice("Test03"));

Thanks!:)谢谢!:)

The point is, the parameterless constructor is optional, only if there is no other constructor defined at all.问题的关键是,参数的构造函数是可选的,只要没有在所有定义的其它构造。 It will be auto-generated in this special case, so that the compiler is able to create instances of the type.在这种特殊情况下,它将自动生成,以便编译器能够创建该类型的实例。 But as soon as you define a constructor, the compiler assumes that every constructor which wasn't defined was left out deliberately.但是一旦您定义了构造函数,编译器就会假定每个未定义的构造函数都被有意地排除在外。 This means once you have defined the constructor, which takes the string parameter, you also have to explicitly define the parameterless default constructor (if you want to) - which apparently you haven't.这意味着一旦您定义了接受string参数的构造函数,您还必须显式定义无参数的默认构造函数(如果您愿意)——显然您还没有。 That's why the initialization list fails, as it invokes an undefined parameterless constructor.这就是初始化列表失败的原因,因为它调用了一个未定义的无参数构造函数。

// Invokes the parameterless default constructor
new AudioListaDevice { AudioDeviceItem = "Test 01"}

The solution is to define a default constructor:解决方案是定义一个默认构造函数:

public class AudioListaDevice : INotifyPropertyChanged
{ 
  // Parameterless default constructor
  public AudioListaDevice() : this(string.Empty)
  {
  }

  public AudioListaDevice(string audioDeviceItem)
  {
    this.AudioDeviceItem = audioDeviceItem;
  }

  private string _AudioDeviceItem;
  public string AudioDeviceItem
  {
    get { return _AudioDeviceItem; }
    set { _AudioDeviceItem = value; OnPropertyChanged("AudioDeviceItem"); }
  }

  public void OnPropertyChanged(string propertyName)
  {
    if (PropertyChanged != null)
    {
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;
}

Alternatively, if you don't want to define a parameterless constructor, then use the existing constructor for instantiation properly:或者,如果您不想定义无参数构造函数,则正确使用现有构造函数进行实例化:

private ObservableCollection<AudioListaDevice> _audiodevicesitem = new ObservableCollection<AudioListaDevice>
{
  //Adding my first Item to test it
  new AudioListaDevice("Test 01"),
  new AudioListaDevice("Test 02")
};

Recommended read:推荐阅读:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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