加载新的WPF/C#窗口时要触发的最后一个事件是什么?

Ben*_*osh 19 c# wpf events

我正在尝试为我的应用程序加载首选项窗口,我希望最初禁用应用按钮,然后在更新首选项时,再次启用应用按钮.我有一些绑定到首选项对象的控件数据,发生的是窗口加载后,组合框事件被触发.在一切稳定之后,是否有任何事件可以保证在最后发生?

这是我的代码的样子(窗口加载后始终启用应用按钮):

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _preferencesData = new PreferencesDataContext();
    LayoutRoot.DataContext = _preferencesData;
    ButtonApply.IsEnabled = false;
}

private void ComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
    ButtonApply.IsEnabled = true;
}
Run Code Online (Sandbox Code Playgroud)

是否有趣的是,这只发生在文本框和组合框中,而不是复选框或单选按钮.

Ray*_*rns 53

简单需求的最佳解决方案

对于您的简单需求,Joseph的答案是迄今为止最好的解决方案:只需使用数据绑定并让数据模型处理它.

回答提出的问题

在完全加载所有事件并且所有事件都被触发之后,当你确实需要控制时,有更复杂的场景.没有单个事件发生在"死亡之后",但使用Dispatcher队列很容易有效地滚动自己的事件.

这是怎么做的:

Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() =>
{
  var x = ComputeSomething(1, 2, 3);
  DoSomething(x, "Test");
}));
Run Code Online (Sandbox Code Playgroud)

当WPF以比ContextIdle更高的优先级完成所有内容时,{}内的所有内容都将被执行,后者包括所有事件处理程序,加载的事件,输入事件,呈现等.

创建和显示窗口时的事件序列

根据要求,这是创建和显示窗口时WPF中的主要事件序列:

  1. 在创建对象时调用构造函数和getter/setter,包括对正在更新的对象的PropertyChangedCallback,ValidationCallback等以及从它们继承的任何对象

  2. 当每个元素被添加到可视或逻辑树时,其Intialized事件被触发,这导致除了您可能定义的任何特定于元素的初始化之外还应用样式和触发器[注意:逻辑树中的叶子未触发初始化事件如果根源没有PresentationSource(例如Window)

  3. 窗口和所有未折叠的Visuals都是Measured,这会在每个Control上导致ApplyTemplate,这会导致其他对象树构造,包括更多构造函数和getter/setter

  4. 窗口和所有未折叠的Visuals都是Arranged

  5. 窗口及其后代(逻辑和可视)接收Loaded事件

  6. 任何首次设置失败的数据绑定都将重试

  7. 窗口及其后代有机会在视觉上呈现其内容

无论是否显示Window,都会在创建Window时完成步骤1-2.其他步骤通常在窗口显示之前不会发生,但如果手动触发它们可能会更早发生.


Jos*_*eph 11

我只是在systray WPF应用程序中表现出同样的行为.

但是,我没有使用事件处理.我只是将我的按钮的Enabled属性绑定到我的ViewModel中的属性,并在需要该行为时更新属性.


And*_*eas 11

Window.ContentRendered事件满足了我的要求.


Aus*_*nen 5

您可以使用ManagedSpy自行解决这个问题.

http://msdn.microsoft.com/en-us/magazine/cc163617.aspx