【问题标题】:Potential bug in the .NET Framework VisualTreeHelper class.NET Framework VisualTreeHelper 类中的潜在错误
【发布时间】:2016-05-18 14:52:12
【问题描述】:

我相信在 .NET Framework 中发现了一个错误。

总结:

我目前正在开发 Windows Phone 8.1 应用程序,并尝试使用 VisualTreeHelper.GetOpenPopups() 方法。作为参数,我使用了Window.Current

它无法找到任何当前显示的由MessageDialog 制作的弹出窗口(即使MessageDialog 继承自 (Windows.UI.Popups)。

但是,我能够找到当前显示的任何弹出窗口,这些弹出窗口是我从 ContentDialog 类创建的,因此这里似乎存在错误。

在我将其归类为错误之前,谁能确认我没有从根本上误解某些东西?

深入示例:

我有两个项目正在运行。其中哪个是我的 Windows Phone 项目,另一个是测试我的应用的 NUnit 项目。

在我的 NUnit 项目中,我的代码归结为:

OpenApp(); //Done through Winium which I use for UI testing
OpenPopup; //This works fine, the popup comes.

//Give my root-app window as current window, so it iteratively searches from there.
var popupcount = VisualTreeHelper.GetOpenPopups(Window.current); 

如果我在我的 Windows Phone 项目中使用这行代码:

var m = new MessageDialog("");
var popupCount = m.ShowAsync();

那么VisualTreeHelper返回的popupcount在我的NUnit项目中为0。

但是,如果我使用这行代码:

var m = new ContentDialog("");
var popupCount = m.ShowAsync();

不是 0。

【问题讨论】:

  • 忘记等待异步方法不是框架错误。正确的名称是“线程竞赛错误”。
  • 我的错。在这两种情况下,我都会调用:“await m.showAsync()”。我只是想简化代码。这里的情况是我的 UWP 应用程序正在运行,它正在等待弹出的结果(因此我使用 await,所以我可以等待用户的回答)。在另一个项目中,我正在 UI 测试我的代码,所以当显示弹出窗口时,我尝试访问弹出窗口,以便单击其中的按钮。但是,我无法访问弹出窗口,因为我在 VisualTreeHelper 中找不到按钮的句柄。
  • @oPolo 您应该更新您的问题以表明您正在使用async ,并确保添加所有可能的细节,然后才能认真对待在框架中发现错误的声明。跨度>
  • 会的。感谢您的反馈。

标签: c# .net xaml uwp


【解决方案1】:

VisualTreeHelper.GetOpenPopups method 可以从目标 Window 检索所有打开的弹出控件的集合。但是MessageDialog 不在您的Window 中。要查看这一点,您可以在 Windows 10 移动模拟器中运行代码以利用 Live Visual Tree。以下是我用来测试的代码:

XAML:

<StackPanel Margin="50">
    <Button Click="MessageDialog_Click">Show
MessageDialog</Button>
    <Button Margin="0,20,0,0" VerticalAlignment="Center" Click="ContentDialog_Click">Show ContentDialog</Button>
</StackPanel>

代码隐藏:

private async void MessageDialog_Click(object sender, RoutedEventArgs e)
{
    var messageDialog = new MessageDialog("MessageDialog Test");

    await messageDialog.ShowAsync();
}

private async void ContentDialog_Click(object sender, RoutedEventArgs e)
{
    var contentDialog = new ContentDialog()
    {
        Title = "ContentDialog Test",
        Content = "This is ContentDialog Test",
        PrimaryButtonText = "Ok"
    };

    await contentDialog.ShowAsync();
}

显示 MessageDialog 时,[PopupRoot] 中没有任何内容。

当您显示 ContentDialog 时,它位于 [PopupRoot] 中。

所以当您使用VisualTreeHelper.GetOpenPopups 方法和MessageDialog 时,计数为0。但对于ContentDialog,它不是0。

其实MessageDialog class并没有继承自Windows.UI.Popups,它只是在Windows.UI.Popups命名空间中,实现了IMessageDialog接口。您可以在 Visual Studio 中使用“Go To Definition(F12)”找到它。

Popup classWindows.UI.Xaml.Controls.Primitives 命名空间中,继承自FrameworkElement class。它们不相关。

【讨论】:

  • 非常感谢您的反馈!!!这是一个真正彻底的答案,我没想到!那么 VisualTreeHelper 找不到任何弹出窗口是有道理的。我也只是在阅读您的答案后尝试检查,确实消息对话框 XAML 元素的顶级父级是我手机上的某个根系统进程,而不是我的应用程序。虽然有点奇怪的设计选择,因为几乎不可能对 messagedialog-elements 进行单元测试... ContentDialogs 必须这样做,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 2022-01-20
  • 2019-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多