我有一个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()
所以我们可以看到加载的事件没有触发。
答案 0 :(得分:1)
在这个实现中我发现有几件事情很奇怪,但让我们从你的实际问题开始。
<强> 1。您的GenericPopup
用户控件永远不会显示!
您正在显示的弹出窗口是用户控件的一部分,而不是相反。弹出窗口显示网格,而不是GenericPopup
控件。这就是Loaded
事件未被提出的原因。
我想到了两个解决方案(我肯定会选择第一个解决方案):
- 在代码中创建Popup
并将整个GenericPopup
控件放入其中;或
- 订阅Popup
或Grid
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。嗯,现在就是这样。第一点是真正的问题,其余的只是我认为可以改进一些的东西。希望它可以帮助您按照自己喜欢的方式工作。 :)