加载的事件不会在用户控件中触发

本文关键字:控件 用户 事件 加载 | 更新日期: 2023-09-27 18:34:38

我有一个用户控件,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;                
            }
        }
    }
}

我按如下方式创建用户控件:

        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. 您的GenericPopup用户控件永远不会显示!

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

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

2. 您需要ItemsControl吗?

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

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

3. 其他一些评论

这更像是一种首选项,但我会在 XAML 中定义所有RowDefinition,然后只更改代码中所需的内容。

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

我会像这样定义IsOpen属性:

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

这样,它将始终自动正确。您不必手动更新它,也没有机会忘记这样做。
如果你真的希望它是静态的,我想吸气器可能看起来像这样:return Current != null .

附言好吧,现在就是这样。第一点是真正的问题,其余的只是我认为可以改进一点的东西。希望它能帮助您随心所欲地工作。:)