我这里有些东西让我措手不及.
我有一个带有项目的Ob的ObservableCollection.我还有一个附加到CollectionChanged事件的事件处理程序.
当您清除集合,将导致以e.Action的CollectionChanged事件设置为NotifyCollectionChangedAction.Reset.好的,这很正常.但奇怪的是,e.OldItems或e.NewItems都没有任何内容.我希望e.OldItems可以填充从集合中删除的所有项目.
有没有人见过这个?如果是这样,他们是如何绕过它的?
一些背景:我使用CollectionChanged事件来附加和分离另一个事件,因此如果我没有在e.OldItems中获取任何项目......我将无法从该事件中分离出来.
澄清: 我知道文档并没有完全声明它必须以这种方式行事.但对于其他所有行动,它都会告诉我它做了什么.所以,我的假设是它会告诉我......在清除/重置的情况下.
如果您希望自己重现,下面是示例代码.首先关闭xaml:
<Window
x:Class="ObservableCollection.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Height="300"
Width="300"
>
<StackPanel>
<Button x:Name="addButton" Content="Add" Width="100" Height="25" Margin="10" Click="addButton_Click"/>
<Button x:Name="moveButton" Content="Move" Width="100" Height="25" Margin="10" Click="moveButton_Click"/>
<Button x:Name="removeButton" Content="Remove" Width="100" Height="25" Margin="10" Click="removeButton_Click"/>
<Button x:Name="replaceButton" Content="Replace" Width="100" Height="25" Margin="10" Click="replaceButton_Click"/>
<Button x:Name="resetButton" Content="Reset" Width="100" Height="25" Margin="10" Click="resetButton_Click"/>
</StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)
接下来,代码背后:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media; …Run Code Online (Sandbox Code Playgroud) 我经常遇到如下代码:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,if条件确保foreach块仅在items不为null时才会执行.我想知道这种if情况是否真的需要,或者foreach是否会处理这种情况items == null.
我的意思是,我可以简单地写一下
foreach(T item in items)
{
//...
}
Run Code Online (Sandbox Code Playgroud)
不用担心是否items为空?是if条件多余的?或者这取决于该类型的items或可能的T呢?
我有一个可观察的集合...... SelectableDataContext<T>在泛型类SelectableDataContext<T>中......有两个私有成员变量
当IsSelected属性发生更改时...我的集合的已更改属性未触发.
我认为它应该解雇...因为它Reset在INotifyCollectionChangedAction.
问题:
ItemsControl(或从中派生的控件ItemsControl).ItemsControl.ItemsSource属性绑定到ObservableCollectionViewModel中的a.ObservableCollection.ObservableCollection.背景:
这似乎是许多WPF开发人员遇到的常见问题.有人问过几次:
ObservableCollection没有注意到它中的Item何时发生变化(即使使用INotifyPropertyChanged)
ObservableCollection和Item PropertyChanged
我的实施:
当Item更改时,我尝试在Notify ObservableCollection中实现接受的解决方案.基本思想是PropertyChanged在MainWindowViewModel中为每个项目连接一个处理程序ObservableCollection.更改项目的属性时,将调用事件处理程序,并以某种方式更新视图.
我无法让实现工作.这是我的实施.
的ViewModels:
class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName = "")
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Run Code Online (Sandbox Code Playgroud)
项目视图模型:
class EmployeeViewModel : ViewModelBase
{
private int _age;
private string _name;
public int Age
{ …Run Code Online (Sandbox Code Playgroud) 我为ObservableCollection创建了一个包装器集合,它订阅每个PropertyChanged事件并将其重新抛出为自己的事件ItemPropertyChanged.我使用与我在此描述的方法类似的方法做到了这一点.有没有更好的办法?我错过了另一个已经有这种行为的.NET集合吗?
当集合的属性发生更改时(添加/删除列表中的项目工作正常),我在更新包含ObservableCollection的Listbox时遇到问题:
listbox已设置ItemsSource="{Binding Path=AllPerson}",后面的代码中的数据上下文设置如下this.DataContext = allPersonClass;.
allPersonClass 包含 ObservableCollection<Person> allPerson
类Person包含Name等属性.
我已经覆盖了人员ToString返回Name属性的方法,因此listBox显示有效数据
我试图制作Person工具INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void onPropertyChanged(object sender, string propertyName) {
if (this.PropertyChanged != null) {
PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
}
}
public string Name {
get { return name; }
set {
name = value;
onPropertyChanged(this, "allPersonClass");
}
}
Run Code Online (Sandbox Code Playgroud)
并且在每个属性setter onPropertyChanged(this, "propertyName");中都执行了但listBox永远不会更新已创建的项目
知道什么可能是错的吗?
这是带有listBox xaml的窗口
<Button x:Name="btnDetail" Content="Detail" HorizontalAlignment="Left" Margin="361,249,0,0" VerticalAlignment="Top" Width="75" Click="ButtonDetailClick"/>
<ListBox …Run Code Online (Sandbox Code Playgroud) 我是WPF的新手,并尝试使用MVVM框架构建示例应用程序.我的应用程序有一个xaml文件,其中包含一些用于输入客户信息的文本框,用于显示状态的组合框和一个保存按钮.所有数据绑定都是通过ViewModel(CustomerViewMode)完成的,ViewModel引用了Model(Customer),包含必需的字段及其Getter,setter.viewModel具有CustomerList属性.单击"保存"按钮,我想在ListBox中显示Customer的FirstName和LastName属性.这就是问题所在.我调试了代码,(在后面的代码中单击按钮事件),我可以看到CustomerList有第一个Customer对象及其所有细节,但它没有显示在列表框中.我的代码是:客户(型号);
enter code here
namespace SampleMVVM.Models
{
class Customer : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private String _firstName;
private String _lastName;
private Address _customerAddress;
public String FirstName
{
get { return _firstName; }
set
{
if (value != _firstName)
{
_firstName = value;
RaisePropertyChanged("FirstName");
}
}
}
public String LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
{
_lastName = value;
RaisePropertyChanged("LastName");
}
}
}
public Address CustomerAddress
{
get { return _customerAddress; } …Run Code Online (Sandbox Code Playgroud) 我有以下绑定到 DataGrid 的 ObservableCollection:
public ObservableCollection<Message> Messages = new ObservableCollection<Message>;
Run Code Online (Sandbox Code Playgroud)
XAML:
<DataGrid ItemsSource="{Binding Path=Messages}">
Run Code Online (Sandbox Code Playgroud)
我在启动时对其进行排序,使用默认视图:
ICollectionView view = CollectionViewSource.GetDefaultView(Messages);
view.SortDescriptions.Add(new SortDescription("TimeSent", ListSortDirection.Descending));
Run Code Online (Sandbox Code Playgroud)
一切正常,但问题是每当我向 Messages 集合添加新消息时,它只会附加到列表的底部,而不是自动排序。
Messages.Add(message);
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?我确信我可以通过每次添加项目时刷新视图来解决这个问题,但这似乎是错误的做法(更不用说性能方面了)。