加载的事件不会在UserControl中触发

时间:2014-12-17 13:10:19

标签: c# user-controls windows-phone-8.1

我有一个UserControl,Loaded事件永远不会触发。为什么会这样?我该如何解雇?

布局定义为:

<UserControl
    x:Class="MyProject.WP81.GenericPopup"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyProject.WP81"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400" Margin="0,1,0,-1"
    Loaded="GenericPopup_Loaded">

    <Popup Name="hostPopup">
        <Grid Name="contentGrid" VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition x:Name="statusBarRow" Height="0" />
            </Grid.RowDefinitions>

            <ItemsControl Name="itemsControl" VerticalAlignment="Center" HorizontalAlignment="Center" />

            <Border Grid.Row="2" Background="#7F000000" />
        </Grid>
    </Popup>
</UserControl>

将逻辑定义为:

namespace MyProject.WP81
{
    public sealed partial class GenericPopup : UserControl
    {
        public static bool IsOpen { get; private set; }
        public static GenericPopup Current { get; private set; }

        private UserControl _content;
        public GenericPopup(UserControl content)
        {
            Trace.trace("GenericPopup::Ctor()");
            _content = content;

            this.InitializeComponent();

            Initialise();

            SetContent(content);
        }

        private void Initialise()
        {
            Trace.trace("GenericPopup::Initialise()");

            RowDefinition rd = new RowDefinition();
            rd.MinHeight = Window.Current.Bounds.Height;
            rd.Height = new GridLength(Window.Current.Bounds.Height);
            contentGrid.RowDefinitions.Add(rd);
            contentGrid.Height = Window.Current.Bounds.Height;
            contentGrid.Width = Window.Current.Bounds.Width;
            contentGrid.Background = new SolidColorBrush(Colors.Black);
            contentGrid.Background.Opacity = 0.7;
            statusBarRow.MinHeight = Window.Current.Bounds.Height;
            statusBarRow.Height = new GridLength(Window.Current.Bounds.Height);

            Unloaded += (s, e) =>
            {
                Trace.trace("GenericPopup::Unloaded()");
                HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
            };

            Trace.trace("GenericPopup::Initialised()");
        }

        private void GenericPopup_Loaded(object sender, RoutedEventArgs e)
        {
            Trace.trace("GenericPopup::GenericPopup_Loaded()");
            HardwareButtons.BackPressed += HardwareButtons_BackPressed;
            _content.Width = Window.Current.Bounds.Width;
        }

        public void SetContent(UserControl content)
        {
            Trace.trace("GenericPopup::SetContent()");
            _content = content;

            _content.Width = Window.Current.Bounds.Width;

            itemsControl.Items.Add(_content);
        }


        public async void Show()
        {
            Trace.trace("GenericPopup::Show()");
            this.Height = Window.Current.Bounds.Height;
            this.Width = Window.Current.Bounds.Width;

            hostPopup.IsOpen = true;
            IsOpen = hostPopup.IsOpen;
            Current = this;
        }

        public static void HideCurrent()
        {
            if (Current != null)
            {
                Current.Hide();
            }
        }

        internal void Hide()
        {
            //WinterfellToast.Show("msg popup:", "hide");

            hostPopup.IsOpen = false;
            IsOpen = hostPopup.IsOpen;
            Current = null;
        }

        void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
        {
            Trace.trace("GenericPopup::HardwareButtons_BackPressed()");
            e.Handled = true;

            if (hostPopup.IsOpen)
            {
                hostPopup.IsOpen = false;                
            }
        }
    }
}

我按如下方式创建UserControl:

        var popopContent = new PopupContentUserControl(); 

        // any UserControl can be passed in as the content of the popup.
        // better if it's small though.
        _genericPopup = new GenericPopup(popopContent);
        _genericPopup.Show();    

我可以在跟踪中看到以下内容:

> 13:00:53.777  GenericPopup::Show() 
> 13:00:53.763  GenericPopup::SetContent() 
> 13:00:53.763  GenericPopup::Initialised() 
> 13:00:53.747  GenericPopup::Initialise() 
> 13:00:53.730  GenericPopup::Ctor()

所以我们可以看到加载的事件没有触发。

1 个答案:

答案 0 :(得分:1)

在这个实现中我发现有几件事情很奇怪,但让我们从你的实际问题开始。

<强> 1。您的GenericPopup用户控件永远不会显示!

您正在显示的弹出窗口是用户控件的一部分,而不是相反。弹出窗口显示网格,而不是GenericPopup控件。这就是Loaded事件未被提出的原因。

我想到了两个解决方案(我肯定会选择第一个解决方案):
- 在代码中创建Popup并将整个GenericPopup控件放入其中;或
- 订阅PopupGrid Loaded活动。

<强> 2。您需要ItemsControl吗?

我不确定你追求的是什么,但我猜想这个想法是在一个GenericPopup中有一个项目。使用仅显示一个元素的ContentControl或某个控件会更合适。

此外,您的方法SetContent不是设置内容,而是添加,因此您可能想要更改其名称或其名称行为。

第3。其他一些评论

这更像是一种偏好,但我在XAML中定义了所有RowDefinition,然后只更改了代码中我需要的内容。

另外,Border不应该Grid.Row="0" Grid.RowSpan="2"吗?

我定义IsOpen属性,如下所示:

public bool IsOpen {
    get { return this.hostPopup.IsOpen; }
}

这种方式总是会自动纠正。你不必手动更新它,也没有机会忘记这样做 如果你真的希望它是静态的,我猜这个getter看起来像这样:return Current != null

P.S。嗯,现在就是这样。第一点是真正的问题,其余的只是我认为可以改进一些的东西。希望它可以帮助您按照自己喜欢的方式工作。 :)