【发布时间】:2012-08-09 00:13:58
【问题描述】:
我在 View 的构造函数中将我的 View 的 DataContext 设置为我的 ViewModel 的一个实例,只是标准的东西。此后不久,UPDATE_RECENT_DOCUMENTS_LIST 事件从我的 ViewModel 正确捕获的事件聚合器中触发。更改了属性并调用了 onPropertyChanged 方法,但由于 PropertyChanged 事件为空而失败。
接下来我要做的是对 UI 执行一个操作,它会引发一个 CREATE_PROJECT 事件,并且同一个 ViewModel 正在接收事件,除了现在,PropertyChanged 事件不再为空,一切都按预期工作.
在设置 DataContext 之后,在它注册到 PropertyChanged 事件之前是否需要经过特定的时间量?是否有一个我可以等待的事件来确保 PropertyChanged 事件不为空?
此外,在集成 Prism 并使用非常方便的 EventAggregator 之后,我没有使用标准 .NET 事件遇到这个问题。
我在 View 和 ViewModel 后面显示我的代码,为简洁起见省略了 View XAML。
ToolBarView.xaml.cs:
namespace ToolBarModule
{
public partial class ToolBarView : UserControl
{
public ToolBarView(ToolBarViewModel toolBarViewModel)
{
InitializeComponent();
this.DataContext = toolBarViewModel;
}
}
}
ToolBarViewModel.cs
namespace ToolBarModule
{
public class ToolBarViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ToolBarCommands baseCommands;
private IEventAggregator eventAggregator;
private KickStartEvent kickStartEvent;
private SubscriptionToken subscriptionToken;
private ObservableCollection<IDocumentReference> recentDocuments = new ObservableCollection<IDocumentReference>();
private ActionCommand newTest;
private ActionCommand openTest;
private ActionCommand saveTest;
private ActionCommand exitApplication;
public ToolBarViewModel(){}
public ToolBarViewModel(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
baseCommands = new ToolBarCommands(eventAggregator);
kickStartEvent = eventAggregator.GetEvent<KickStartEvent>();
subscriptionToken = kickStartEvent.Subscribe(kickStartEventHandler, ThreadOption.UIThread, true, toolBarEventHandlerFilter);
}
public ICommand NewTest
{
get
{
if (newTest == null)
{
newTest = new ActionCommand(baseCommands.NewTestAction);
}
return newTest;
}
}
public ICommand OpenTest
{
get
{
if (openTest == null)
{
openTest = new ActionCommand(baseCommands.OpenTestAction);
}
return openTest;
}
}
public ICommand SaveTest
{
get
{
if (saveTest == null)
{
saveTest = new ActionCommand(baseCommands.SaveTestAction);
}
return saveTest;
}
}
public ICommand ExitApplication
{
get
{
if (exitApplication == null)
{
exitApplication = new ActionCommand(baseCommands.ExitApplicationAction);
}
return exitApplication;
}
}
public ObservableCollection<IDocumentReference> RecentDocuments
{
get
{
return recentDocuments;
}
set
{
recentDocuments = value;
onPropertyChanged("RecentDocuments");
}
}
private void onPropertyChanged(string propertyChanged)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(propertyChanged));
}
}
private void kickStartEventHandler(KickStartEventsArgs e)
{
switch (e.EventType)
{
case KickStartEventsArgs.KickStartEventType.CREATE_PROJECT:
onPropertyChanged("RecentDocuments");
break;
case KickStartEventsArgs.KickStartEventType.UPDATE_RECENT_DOCUMENTS_LIST:
RecentDocuments.Clear();
foreach (IDocumentReference recentDocs in e.KickStartTestList)
{
RecentDocuments.Add(recentDocs);
}
onPropertyChanged("RecentDocuments");
break;
}
}
}
}
【问题讨论】:
-
你在 XAML 中命名了你的 UserControl 吗?
-
提供您的 UserControl 的 XAML。
-
您是自己创建 ToolBarView 还是使用 Resolve 或 RegionManager ?....也许您需要等到控件已加载到 Visual 树中...即等到 Loaded 事件之后……如果您愿意,可以在 Loaded 事件中设置 DataContext
-
感谢大家的cmets。 @colinsmith - 我确实尝试在我发布之前在加载的事件中设置 DataContext,但这并没有帮助。我还验证了事件在 DataContext 设置后触发,这让我相信实际绑定发生在 DataContext 命令之后 >t0。
标签: c# wpf prism datacontext propertychanged