我有两个班级:
public class Person
{
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public ObservableCollection<AccountDetail> Details
{
get { return details; }
set { details = value; }
}
public ObservableCollection<AccountDetail> Phones
{
get
{
ObservableCollection<AccountDetail> phones;
phones = new ObservableCollection<AccountDetail>();
foreach (AccountDetail detail in Details)
{
if (detail.Type == DetailType.Phone)
{
phones.Add(detail);
}
}
return phones;
}
set
{
ObservableCollection<AccountDetail> phones;
phones = value;
foreach (AccountDetail detail in Details)
{
if (detail.Type == DetailType.Phone)
{
Details.Remove(detail);
}
}
foreach (AccountDetail detail in phones)
{
if (!string.IsNullOrEmpty(detail.Value))
{
Details.Add(detail);
}
}
}
}
private string firstName;
private string lastName;
private ObservableCollection<AccountDetail> details;
}
和
public class AccountDetail
{
public DetailType Type
{
get { return type; }
set { type = value; }
}
public string Value
{
get { return this.value; }
set { this.value = value; }
}
private DetailType type;
private string value;
}
在我的XAML文件中,我有一个名为PhonesListBox的ListBox
,它是绑定到电话列表的数据(Person
对象的属性):
<Window.Resources>
<!-- Window controller -->
<contollers:PersonWindowController
x:Key="WindowController" />
</Window.Resources>
...
<ListBox
Name="PhonesListBox"
Margin="0,25,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
ItemsSource="{Binding Path=SelectedPerson.Phones,
Source={StaticResource ResourceKey=WindowController}}"
HorizontalContentAlignment="Stretch" />
...
在其后面的代码中,有一个按钮的处理程序,它为PhonesListBox添加一个新项:
private void AddPhoneButton_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<AccountDetail> phones;
phones = (ObservableCollection<AccountDetail>)PhonesListBox.ItemsSource;
phones.Add(new AccountDetail(DetailType.Phone));
}
问题是,新添加的列表框项目未添加到人员的详细信息可观察集合中,即未更新电话属性(永远不会调用set
)。为什么?我哪里弄错了?
感谢所有帮助。
private void AddPhoneButton_Click(object sender, RoutedEventArgs e)
{
PersonWindowController windowController;
ObservableCollection<AccountDetail> details;
windowController = (PersonWindowController)this.FindResource("WindowController");
details = windowController.SelectedPerson.Details;
details.Add(new AccountDetail(DetailType.Phone));
}
这会更新相应的集合,details
而非Phones
(因为电话只是详细信息项子集的视图或getter )。此外,我意识到我甚至不需要电话设置器。我现在面临的问题是我的UI没有更新到对细节集合(以及随后的电话)所做的更改。由于细节和电话都没有变化,我不知道如何或在哪里要求改变房产;他们的收藏成员是。救命。请。
答案 0 :(得分:2)
为什么每次检索ObservableCollection<AccountDetail>
属性时都会创建一个新的Phones
?通常,Person
类将具有类型ObservableCollection<AccountDetail>
的成员字段,该字段将仅在Phones
属性的getter中返回,而不是每次都创建一个新的。例如,在构造Person
的实例时,可以填充此集合。
我不知道这是否能解决您的问题,但似乎应该有所帮助。
答案 1 :(得分:1)
听起来你的ObservableCollection<AccountDetail>
不仅仅包含手机了,所以看起来你确实需要添加CollectionViewSource
的{{1}}:
Filter
答案 2 :(得分:0)
将Person
课改为以下内容应该有效:
public class Person
{
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public ObservableCollection<AccountDetail> Details
{
get { return details; }
set { details = value; }
}
public ObservableCollection<AccountDetail> Phones
{
get
{
if (phones == null)
{
phones = new ObservableCollection<AccountDetail>();
}
phones.Clear();
foreach (AccountDetail detail in Details)
{
if (detail.Type == DetailType.Phone)
{
phones.Add(detail);
}
}
return phones;
}
set
{
phones.Clear();
foreach (var item in value)
{
phones.Add(item);
}
foreach (AccountDetail detail in Details)
{
if (detail.Type == DetailType.Phone)
{
Details.Remove(detail);
}
}
foreach (AccountDetail detail in phones)
{
if (!string.IsNullOrEmpty(detail.Value))
{
Details.Add(detail);
}
}
}
}
private string firstName;
private string lastName;
private ObservableCollection<AccountDetail> details;
public ObservableCollection<AccountDetail> phones;
}
代码未经过测试,可能需要您进行一些更改才能实际工作。
答案 3 :(得分:0)
尝试类似:
public class Person : INotifyPropertyChanged
{
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public ObservableCollection<AccountDetail> Details
{
get { return details; }
set { details = value; }
}
public void AddDetail(AccountDetail detail) {
details.Add(detail);
OnPropertyChanged("Phones");
}
public IEnumerable<AccountDetail> Phones
{
get
{
return details.Where(d => d.Type == DetailType.Phone);
}
}
private string firstName;
private string lastName;
private ObservableCollection<AccountDetail> details;
/// <summary>
/// Called when a property changes.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
您可以从按钮事件处理程序调用AddDetail方法:
private void AddPhoneButton_Click(object sender, RoutedEventArgs e)
{
PersonWindowController windowController;
ObservableCollection<AccountDetail> details;
windowController = (PersonWindowController)this.FindResource("WindowController");
windowController.SelectedPerson.AddDetail(new AccountDetail(DetailType.Phone));
}
为Phones属性提升OnPropertyChanged事件只会导致WPF绑定框架重新查询属性,并在将详细信息列表中添加Phone详细信息后重新评估Linq查询。