是否首选在其Loaded事件处理程序中初始化WPF用户控件?

时间:2016-12-12 12:26:11

标签: c# .net wpf user-controls

假设我有一个WPF UserControl,如下所示:

public partial class SensorSideView
{
    public SensorSideView()
    {
        InitializeComponent();

        Loaded += SensorSideView_Loaded;
        Unloaded += SensorSideView_Unloaded;
    }

    void SensorSideView_Loaded(object sender, RoutedEventArgs e)
    {
        foreach (var section in SensorSideViewController.CurrentSideview.Sections)
            LoadSection(section);
        ...
    }

    void SensorSideView_Unloaded(object sender, RoutedEventArgs e)
    {
        ClearGui();
    }

    private void LoadSection(Section sec)
    {
        var section = new SectionView(sec);
        section.MouseEnter += ucSection_MouseEnter;
        section.MouseLeave += ucSection_MouseLeave;
        section.MouseLeftButtonDown += ucSection_MouseLeftButtonDown;
        section.Unloaded += ucSection_Unloaded;
        section.Loaded += ucSection_Loaded;
        SectionsCanvas.Children.Add(section);
    }

    private void ClearGui()
    {
        foreach (Section sec in SectionsCanvas.Children)
        {
            sec?.RemoveEventHandler();
        }
        SectionsCanvas.Children.Clear();

        ...
    }
}

如您所见,构造函数仅用于稀疏,以设置LoadedUnloaded事件处理程序。相反,大部分设置都延迟到Loaded事件处理程序。

我想知道,这是WPF中常见或推荐的模式吗?难道我只能在构造函数中初始化一次控件,就像通常使用任何其他C#类一样,而不是每次用户打开它时都必须重新初始化它?

我问的原因是因为我继承了这种模式非常普遍的项目。

我在某处读到了WPF对象可以被框架重复使用的原因,这就是为什么我犹豫是否要进行彻底的改变并将初始化逻辑从Loaded处理程序移动到构造函数。

WPF中构建复杂用户控件及其实例变量的一般原则是什么?

1 个答案:

答案 0 :(得分:0)

这是我在OP的问题

下面的评论摘要

你可能会更好地将其分为两个问题 - 一个用于延迟问题,另一个用于最佳实践。

  

是否首选在其Loaded事件处理程序中初始化WPF用户控件?

与大多数事情一样,这取决于。

我更喜欢Loaded而不是构造函数init的一个原因是,在前者中执行的代码知道控件现在已经完全布局并且可见 - 如果您需要知道元素的位置,则非常有用。 [1]

不在构造函数中放入东西的另一个好理由是,它会在您实例化控件时立即执行,而不是在它可见时执行。

如果你有复杂的控件层次结构,其中每个控件在构造函数中都有init,那么实例化树中的第一个控件可能需要一段时间。

延迟

  

半秒或更长时间

根据您发布的代码,我不确定您遇到此延迟的原因。你似乎没有做任何特别的事情。就像我说"你可能会更好地把它分成两个问题 - 一个用于延迟问题,另一个用于最佳实践"

[1] https://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.loaded(v=vs.110).aspx