我是WPF的新手。
我正在尝试将字符串集合绑定到组合框。
public ObservableCollection<string> ListString {get; set;}
Binding和datacontext设置如下
<Window
x:Class="Assignment2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:validators="clr-namespace:Assignment2"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}, Path=.}">
<Grid>
<ComboBox Height="23" HorizontalAlignment="Left" Margin="109,103,0,0" Name="StringComboBox" VerticalAlignment="Top" Width="120" SelectionChanged="StringComboBox_SelectionChanged">
<ComboBox.ItemsSource>
<Binding Path="ListString" BindsDirectlyToSource="True" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"></Binding>
</ComboBox.ItemsSource>
</ComboBox>
我发现这种情况正在发生,因为集合正在更新。如果我写
public MainWindow()
{
InputString = "";
ListString = new ObservableCollection<string>();
ListString.Add("AAA");
ListString.Add("BBB");
ListString.Add("CCC");
InitializeComponent();
}
它确实有效,但如果我在第一行上面移动InitializeComponent()
如下,它就不起作用。
public MainWindow()
{
InitializeComponent();
InputString = "";
ListString = new ObservableCollection<string>();
ListString.Add("AAA");
ListString.Add("BBB");
ListString.Add("CCC");
}
我该怎么办?
答案 0 :(得分:11)
解决了这个问题。按如下方式实现了INotifyPropertyChanged
public partial class MainWindow : Window, INotifyPropertyChanged
修改了访问者,如下所示
private ObservableCollection<string> listString;
public ObservableCollection<string> ListString
{
get
{
return listString;
}
set
{
listString = value;
NotifyPropertyChanged("ListString"); // method implemented below
}
}
并添加了以下事件和方法来引发事件
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(name));
}
}
它起作用B)
答案 1 :(得分:0)
如果将代码更改为
会发生什么<Window
x:Class="Assignment2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:validators="clr-namespace:Assignment2"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox Height="23" HorizontalAlignment="Left" Margin="109,103,0,0" Name="StringComboBox" VerticalAlignment="Top" Width="120" SelectionChanged="StringComboBox_SelectionChanged"
ItemsSource="{Binding ListString, Mode=OneWay}"/>
CS。
public MainWindow()
{
InitializeComponent();
InputString = "";
ListString = new ObservableCollection<string>();
ListString.Add("AAA");
ListString.Add("BBB");
ListString.Add("CCC");
this.DataContext=this;
}
btw:使用mode = twoway设置ItemsSource对我没有意义。你的组合框永远不会为你的viewmodel“创建一个新的itemssource”。
编辑: 我认为你的第一个解决方案是有效的,因为在xaml中设置了DataContext。我假设在调用InitializeComponent()时执行DataContext =“{Binding RelativeSource = {RelativeSource Self},Path =。}”;并且因为您的ListString属性只是一个autoproperty而没有实现INotifyPropertyChanged - 您的主窗口视图不会被通知您的ctor创建新的ListString属性。
public ObservableCollection<string> ListString {get{return _list;}; set{_list=value; OnPropertyChanged("ListString");}}
应该适用于您的两种方法,但您必须为MainWindow类实现INotifyPropertyChanged。
答案 2 :(得分:0)
您可以在后面的代码中设置combobox的项目源,或者在填充列表后再次设置datacontext,或者您可以使用inotifychanged来提高属性更改。
public MainWindow()
{
InitializeComponent();
InputString = "";
ListString = new ObservableCollection<string>();
ListString.Add("AAA");
ListString.Add("BBB");
ListString.Add("CCC");
StringComboBox.ItemsSource = ListString;
}
答案 3 :(得分:0)
在我看来问题是&#34;新的&#34; ListString
。使它成为一个属性(选定的答案)是解决这个问题的一种方法。或者内联即时,或者将它放在InitializeComponent
之前,我相信也没关系。
如果预计会经常进行新增,那么将ObservableCollection
封装在经理类中可能会有所帮助。在使用这样的设置解决我自己的问题后,我发现了这个问题。我通过实现INotifyCollectionChanged
并转发事件来实现它
/// <summary>
/// Maintains an observable (i.e. good for binding) collection of resources that can be indexed by name or alias
/// </summary>
/// <typeparam name="RT">Resource Type: the type of resource associated with this collection</typeparam>
public class ResourceCollection<RT> : IEnumerable, INotifyCollectionChanged
where RT : class, IResource, new()
{
public event NotifyCollectionChangedEventHandler CollectionChanged
{
add { Ports.CollectionChanged += value; }
remove { Ports.CollectionChanged -= value; }
}
public IEnumerator GetEnumerator() { return Ports.GetEnumerator(); }
private ObservableCollection<RT> Ports { get; set; }
private Dictionary<string, RT> ByAlias { get; set; }
private Dictionary<string, RT> ByName { get; set; }
}