在将数组绑定到ListBox时,我注意到了一些奇怪的行为。当我添加具有相同“名称”的项目时,我无法在运行时选择它们 - ListBox变得疯狂。如果我给他们独特的“名字”,它就可以了。任何人都可以解释为什么这是怎么回事?
观点:
<Window x:Class="ListBoxTest.ListBoxTestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ListBoxTest"
Title="ListBoxTestView" Height="300" Width="300">
<Window.Resources>
<local:ListBoxTestViewModel x:Key="Model" />
</Window.Resources>
<Grid DataContext="{StaticResource ResourceKey=Model}">
<ListBox ItemsSource="{Binding Items}" Margin="0,0,0,70" />
<Button Command="{Binding Path=Add}" Content="Add" Margin="74,208,78,24" />
</Grid>
</Window>
视图模型:
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;
namespace ListBoxTest
{
internal class ListBoxTestViewModel : INotifyPropertyChanged
{
private List<string> realItems = new List<string>();
public ListBoxTestViewModel()
{
realItems.Add("Item A");
realItems.Add("Item B");
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public string[] Items
{
get { return realItems.ToArray(); }
}
public ICommand Add
{
// DelegateCommand from Prism
get { return new DelegateCommand(DoAdd); }
}
private int x = 1;
public void DoAdd()
{
var newItem = "Item";
// Uncomment to fix
//newItem += " " + (x++).ToString();
realItems.Add(newItem);
OnPropertyChanged("Items");
}
}
}
答案 0 :(得分:2)
WPF ListBox中的所有项都必须是唯一的实例。由于字符串Interning,具有相同常量值的字符串不是唯一实例。要解决这个问题,您需要将项目封装在比String更有意义的对象中,例如:
public class DataItem
{
public string Text { get; set; }
}
现在,您可以实例化多个DataItem实例并创建ItemDataTemplate以将Text呈现为TextBlock。如果要使用默认呈现,还可以覆盖DataItem ToString()。您现在可以拥有多个具有相同Text但没有问题的DataItem实例。
这个限制可能看起来有点奇怪,但它简化了逻辑,因为现在SelectedItem与列表中项目的SelectedIndex一一对应。它也符合WPF数据可视化方法,它倾向于有意义的对象列表而不是普通字符串列表。