我有以下begginer项目,并有一个奇怪的效果。我希望按钮在每次单击时向ComboBox添加一个元素。
当我启动应用程序时,单击按钮上的n
次,然后打开ComboBox,它会按预期显示n
个项目。但无论我多久点击一次按钮,ComboBox中都没有新项目。
MainWindow.xaml :
<Window x:Class="WPF_binding_combobox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_binding_combobox"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button Content="Add item to combobox" Click="Button_Click" />
<ComboBox ItemsSource="{Binding Path=ComboBoxItems}" />
</StackPanel>
</Window>
MainWindow.xaml.cs (代码隐藏):
namespace WPF_binding_combobox {
using System.Windows;
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
this.DataContext = new La();
}
private void Button_Click(object sender, RoutedEventArgs e) {
La l = this.DataContext as La;
l.AddItem();
}
}
}
La.cs
namespace WPF_binding_combobox {
using System.Collections.Generic;
using System.ComponentModel;
class La : INotifyPropertyChanged {
private int counter;
private IList<string> cbItems;
public IList<string> ComboBoxItems {
get {
return this.cbItems;
}
set {
this.cbItems = value;
this.RaisePropertyChanged("ComboBoxItems");
}
}
public La() {
this.cbItems = new List<string>();
this.counter = 0;
}
public void AddItem() {
var temp = this.ComboBoxItems;
temp.Add("abc" + (++this.counter));
this.ComboBoxItems = temp;
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName) {
var handler = this.PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
我已经尝试过调试器,它告诉我在后备字段中添加了一些项目并调用了RaisePropertyChanged。出于某种原因,UI在第一次点击后没有显示任何变化。
我尝试过设置Mode=OneWay
或Mode=TowWay
,但没有变化。
为什么ComboBox第一次打开后没有得到更新?
答案 0 :(得分:3)
您正在使用IList
无法通知View在初始绑定后添加或删除了项目(如您所说)。
您应该使用ObservableCollection
。顾名思义,它适用于您的View将成为观察者的观察者模式。
public ObservableCollection<string> ComboBoxItems
{
get
{
return cbItems;
}
}
并且在AddItem
中你只需要这个
public void AddItem()
{
ComboBoxItems.Add("abc" + (++this.counter));
}
关闭主题:
如果您想使用MVVM模式,请不要在代码隐藏中编写任何代码。使用委托命令绑定到按钮。 (谷歌会帮忙)。
即使分配DataContext也可以像这样删除XAML
<Window.DataContext>
<myassembly:LA />
</Window.DataContext>
直到那时,在View中有一个局部变量,可以节省你每次施放的麻烦。
private La _dataContext;
public MainWindow()
{
InitializeComponent();
_dataContext = new La();
this.DataContext = _dataContext
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_dataContext.AddItem();
}
答案 1 :(得分:0)
如果您每次要更新{{>> 重置源集合属性时,是否使用ObservableCollection<T>
或IList<T>
并不重要1}}。
您应该使用ComboBox
的单个实例添加所有项目或将源属性设置为 new ObservableCollection
。
如果您稍微修改IList<string>
方法,它会按预期工作:
AddItem()