使内容对话框像 Groove 应用程序中的对话框一样可移动

问题描述 投票:0回答:4

我创建了一个 ContentDialog 来应用样式(我无法将其应用于消息对话框和弹出窗口),但我遇到了问题,它不可移动,或者我无法像出现的框架那样关闭它我单击 Groove 应用程序中的“Connexion”按钮 enter image description here

您有什么想法吗,我可以在 ContentDialog 样式中修改哪一部分,以使此 ContentDialog 可移动并像上面的图像一样关闭它

我正在开发通用应用程序

c# xaml win-universal-app windows-10-universal
4个回答
7
投票

您有什么想法吗,我可以在 ContentDialog 样式中修改哪一部分,以使该 ContentDialog 可移动并像上面的图像一样关闭它。

恐怕

ContentDialog
是不可移动的,并且您在Groove应用程序或系统邮件应用程序中显示的图像也不是
ContentDialog
,实际上,这个“对话框”是由UserDataAccountManager.ShowAddAccountAsync调用的。如果我们使用ProcessMonitor来跟踪这个UI,我们会发现这是一个系统应用程序C:\Windows\SystemApps\Microsoft.AccountsControl_cw5n1h2txyewy。您可能会在SO上的类似问题中看到图片和信息:UWP Modal Window

对于你的问题,我们无法启动像Microsoft.AccountsControl这样的系统应用程序来获取结果,我们只能使用API调用它

UserDataAccountManager.ShowAddAccountAsync
。但您可以创建一个 UWP 应用程序,然后启动此应用程序以获取另一个应用程序的结果,为此,请参阅启动应用程序以获取结果

或者,如果您只想要一个可移动的 UI,您可以在您的应用程序中创建一个新窗口,并更改这个新窗口的大小,使其像

ContentDialog
一样弹出,但是这个新窗口将显示您的应用程序的标题,这可以不被删除。

如何创建新窗口?例如:

    private async void OnClick(object sender, RoutedEventArgs e)
    {
        var newCoreAppView = CoreApplication.CreateNewView();
        var appView = ApplicationView.GetForCurrentView();
        await newCoreAppView.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, async () =>
        {
            var window = Window.Current;
            var newAppView = ApplicationView.GetForCurrentView();

            var frame = new Frame();
            window.Content = frame;

            frame.Navigate(typeof(BlankPage));            
            window.Activate();
            await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newAppView.Id, ViewSizePreference.Default, appView.Id, ViewSizePreference.Default);

        });
    }

如何更改新窗口的大小?例如新窗口显示页面的cs文件中:

public BlankPage()
        {
            this.InitializeComponent();
            this.Loaded += Page_Loaded;
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            var s = ApplicationView.GetForCurrentView();
            s.TryResizeView(new Size { Width = 600, Height = 320 });
        }

这将制作一个宽度为 600、高度为 320 的窗口。


3
投票

这就是我的做法,因为从 4 年来我一直没有找到任何答案:)

                            var dialog = new ContentDialog()
                            {
                                Title = "This is a Title!",
                                ManipulationMode = ManipulationModes.All,
                            };
                            dialog.ManipulationDelta += delegate (object sender, ManipulationDeltaRoutedEventArgs e)
                            {
                                if(!e.IsInertial)
                                    dialog.Margin = new Thickness(
                                        dialog.Margin.Left + e.Delta.Translation.X,
                                        dialog.Margin.Top + e.Delta.Translation.Y,
                                        dialog.Margin.Left - e.Delta.Translation.X,
                                        dialog.Margin.Top - e.Delta.Translation.Y
                                        );
                            };

1
投票

我认为你可以用另一种方式来做:

  1. 创建一个UserControl,定义像弹出窗口一样的UI。
  2. 将 ManipulationMode 设置为 Translate。
  3. 处理要移动的 ManipulationDelta 事件
  4. UserControll(让我们将 CompositeTransform 作为 RenderTransform)。
  5. 根据需要实现动画 在页面中使用 UserControll

0
投票

更新了建议。我使用的是 WinUI 3,但此 UI 方面似乎与 WinUI 和 UWP 的功能相同:

可以限制仅在单击自定义“标题”时才移动

ContentDialog
,类似于
WinForms Modal
对话框的工作方式(但
ContentDialog
不能离开其父窗口)。

使用

ContentDialog
顶部的网格定义 ĥ header 区域。为 PointerPressed 和 PointerReleased 创建事件处理程序:

    <Grid x:Name="HeaderGrid"
        PointerPressed="HeaderGrid_PointerPressed"
        PointerReleased="HeaderGrid_PointerReleased">

在后面的代码中,使用指针事件来设置

ManipulationModes
并订阅/取消订阅自定义操作处理程序,如下所示:

    private void HeaderGrid_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        this.ManipulationMode = ManipulationModes.All;
        this.ManipulationDelta += ManipulationDeltaHandler;
    }

    private void HeaderGrid_PointerReleased(object sender, PointerRoutedEventArgs e)
    {
        this.ManipulationMode = ManipulationModes.None;
        this.ManipulationDelta -= ManipulationDeltaHandler;
    }

    private void ManipulationDeltaHandler(object sender, ManipulationDeltaRoutedEventArgs e)
    {
    if (!e.IsInertial)
        this.Margin = new Thickness(
            this.Margin.Left + e.Delta.Translation.X,
            this.Margin.Top + e.Delta.Translation.Y,
            this.Margin.Left - e.Delta.Translation.X,
            this.Margin.Top - e.Delta.Translation.Y
        );
    }
© www.soinside.com 2019 - 2024. All rights reserved.