我花了很多时间来解决这个问题。
我有一个包含数据的课程:
public class User : INotifyPropertyChanged
{
private int _key;
private string _fullName;
private string _nick;
public int Key
{
get{return _key;}
set { _key = value; NotifyPropertyChanged("Key"); }
}
public string Nick
{
get { return _nick; }
set { _nick = value; NotifyPropertyChanged("Nick"); }
}
public string FullName
{
get { return _fullName; }
set { _fullName = value; NotifyPropertyChanged("FullName"); }
}
public User()
{
Nick = "nickname";
FullName = "fullname";
}
public User(String nick, String name, int key)
{
Nick = nick;
FullName = name;
}
//INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public override string ToString()
{
return string.Format("{0} {1}, {2}", Key, Nick, FullName);
}
}
接下来,我有一个带有observablecollection userClass类的类:
public class UserList : ObservableCollection<UserList>
{
public UserList (){}
~UserList ()
{
//Serialize();
}
public void Serialize(ObservableCollection<UserList> usersColl)
{
FileStream fs = new FileStream("DataFile.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(fs, usersColl);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}
}
public void Deserialize()
{
FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
try
{
BinaryFormatter formatter = new BinaryFormatter();
//users = (Hashtable) formatter.Deserialize(fs);
//usersColl = (ObservableCollection<userClass>)formatter.Deserialize(fs);
}
catch (SerializationException e)
{
MessageBox.Show(" Error: " + e.Message);
throw;
}
finally
{
fs.Close();
}
}
}
事实上,经过大量的编辑测试后,大部分代码都无法正常工作,比如序列化。但是数据绑定和绑定不是我现在要解决的问题。
所以我有这个集合,并希望将它绑定到listBox。 我尝试了几种方法,但还没有开始工作。
我试过的最后一个给了我写错误:
无法解析资源“用户”。
<ListBox Grid.Column="0" Name="userViewLeft" ItemsSource="{Binding Source={StaticResource users} }" />
答案 0 :(得分:28)
需要注意的一些要点
public
而不是private
。private
。class
。ItemsSource
应该按照数据的范围,在我的例子中,类范围内的用户列表和我在Window Loaded事件上提供了ItemSource。这是一个完整的示例代码,在这里我已经嵌套了ListBox中的Grid Control,因为稍后您可以更改VirtualizingStackPanel的ListBox属性。
因此,当您在列表上进行大量更新时,它会带来巨大的性能提升。
另外,您可以使用BindingList
,这在我看来比ObservableCollection
表现更好。
用户类:
public class User : INotifyPropertyChanged
{
private int _key;
private string _fullName;
private string _nick;
public int Key
{
get { return _key; }
set { _key = value; NotifyPropertyChanged("Key"); }
}
public string NickName
{
get { return _nick; }
set { _nick = value; NotifyPropertyChanged("NickName"); }
}
public string Name
{
get { return _fullName; }
set { _fullName = value; NotifyPropertyChanged("Name"); }
}
public User(String nick, String name, int key)
{
this.NickName = nick;
this.Name = name;
this.Key = key;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public override string ToString()
{
return string.Format("{0} {1}, {2}", Key, NickName, Name);
}
}
用户列表类
public class Users : ObservableCollection<User>
{
public Users()
{
Add(new User("Jamy", "James Smith", Count));
Add(new User("Mairy", "Mary Hayes", Count));
Add(new User("Dairy", "Dary Wills", Count));
}
}
<强> XAML:强>
<Grid>
<Button Content="Start" Height="23" HorizontalAlignment="Left" Margin="416,12,0,0" x:Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<ListBox x:Name="UserList" HorizontalContentAlignment="Stretch" Margin="12,41,12,12">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Key}" Margin="3" Grid.Column="0" />
<TextBlock Text="{Binding NickName}" Margin="3" Grid.Column="1" />
<TextBlock Text="{Binding Name}" Margin="3" Grid.Column="2" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
XAML代码背后:
public partial class MainWindow : Window
{
public static Users userslist = new Users();
DispatcherTimer timer = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
timer.Interval = DateTime.Now.AddSeconds(10) - DateTime.Now;
timer.Tick += new EventHandler(timer_Tick);
UserList.ItemsSource = userslist;
}
void timer_Tick(object sender, EventArgs e)
{
userslist.Add(new User("Jamy - " + userslist.Count, "James Smith", userslist.Count));
userslist.Add(new User("Mairy - " + userslist.Count, "Mary Hayes", userslist.Count));
userslist.Add(new User("Dairy - " + userslist.Count, "Dary Wills", userslist.Count));
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (button1.Content.ToString() == "Start")
{
button1.Content = "Stop";
timer.Start();
}
else
{
button1.Content = "Start";
timer.Stop();
}
}
}
答案 1 :(得分:2)
你需要做两件事:
首先,将包含DataContext
的任何元素(Window
/ UserControl
/ whatever)的ListBox
设置为如下所示的对象:
public class ViewModel
{
public ViewModel() { this.users = new userListClass(); }
public userListClass users { get; private set; }
}
这是您的视图模型,它是您要绑定的内容。
其次,将绑定更改为ItemsSource="{Binding Path=users}"
。这转换为“将ItemsSource
属性的值设置为users
上的属性this.DataContext
的值。因为DataContext
是从父级继承的,所以你设置了到上面的ViewModel
班级,您的ListBox
现在会显示您的用户列表。