我有一个名为IssuesView
的类,它实现了INotifyPropertyChanged
。此类包含ObservableCollection<Issue>
,并将其公开为DependencyProperty
,称为Bindings
消费问题。它定义如下 -
public class IssuesView : DependencyObject, INotifyPropertyChanged
{
public Issues Issues
{
get { return (Issues)GetValue(IssuesProperty); }
set
{
SetValue(IssuesProperty, value);
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Issues"));
}
}
}
// Using a DependencyProperty as the backing store for Issues. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IssuesProperty =
DependencyProperty.Register("Issues", typeof(Issues), typeof(IssuesView), new UIPropertyMetadata(null));
public IssuesView()
{
Refresh();
}
public void Refresh()
{
this.Issues = new Issues();
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
我有一个像这样宣布的测试页 -
<Page x:Class="Tracker.Pages.DEMO"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cont="clr-namespace:Tracker.Controls"
Title="DEMO">
<StackPanel>
<Button Click="Button_Click">Change</Button>
<cont:IssueTimeline IssuesForTimeline="{Binding Source={StaticResource issuesView},Path = Issues}"/>
</StackPanel>
IssuesView
类在Application.Resources
中定义
现在在按钮的事件中我有这个代码 -
private void Button_Click(object sender, RoutedEventArgs e)
{
IssuesView iv = Application.Current.FindResource("issuesView") as IssuesView;
if (!once)
{
foreach (Issue i in iv.Issues)
{
i.DormantFor = new TimeSpan(30, 0, 0, 0);
i.AssignedUserID = 12;
i.Name = "MyName";
i.Priority = Issue.Priorities.Critical;
i.Status = Issue.Statuses.New;
i.Summary = "NewSummary";
}
once = true;
}
else
{
iv.Refresh();
}
曾经是一个简单的布尔值来测试集合与重新填充的变异。
第一个按钮单击会更改集合的项目,并且UI会正确更新,因为项目实现了INotifyPropertyChanged,但第二次单击会重新填充集合,但即使事件不为null并且正常触发,也不会更新UI。
为什么UI不会在第二次点击时更新?我怎样才能使重新填充集合会导致UI更新?
答案 0 :(得分:2)
首先:没有理由为DependencyProperties实现INotifyProperty
更改。 DependencyProperties知道它们何时发生变化。
第二:我的代码中没有ObservableCollection
。
第三:我不完全清楚(从您发布的代码中)您在第一次点击中修改的问题来自哪里。我假设从另一个行动,而不是在这里发布。
如果我假设您想要通过第二次单击清除问题列表(因为我不知道Issues
构造函数的作用),我是否正确?
答案 1 :(得分:1)
你真的需要简化你的repro。我可以看到它有些不对劲,但如果没有看到所有,就无法帮助解决问题。这是我简单的复制品,效果很好。
Window1.xaml:
<Window x:Name="_root" x:Class="CollectionRepro.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 DataContext="{Binding ElementName=_root}">
<ItemsControl ItemsSource="{Binding Issues}"/>
<Button x:Name="_addButton">Add</Button>
<Button x:Name="_resetButton">Reset</Button>
</StackPanel>
</Window>
Window1.xaml.cs:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
namespace CollectionRepro
{
public partial class Window1 : Window
{
public static readonly DependencyProperty IssuesProperty = DependencyProperty.Register("Issues",
typeof(ICollection<string>),
typeof(Window1));
public ICollection<string> Issues
{
get { return (ICollection<string>)GetValue(IssuesProperty); }
set { SetValue(IssuesProperty, value); }
}
public Window1()
{
InitializeComponent();
Reset();
_addButton.Click +=new RoutedEventHandler(_addButton_Click);
_resetButton.Click += new RoutedEventHandler(_resetButton_Click);
}
void _resetButton_Click(object sender, RoutedEventArgs e)
{
Reset();
}
void _addButton_Click(object sender, RoutedEventArgs e)
{
Issues.Add("Another issue");
}
private void Reset()
{
Issues = new ObservableCollection<string>();
}
}
}