WPF Modern UI 单击 "Link" 后弹出一个现代对话框

WPF Modern UI pop up a modern dialog after clicking a "Link"

我正在使用 WPF Modern UI,我试图在单击 Link 后弹出 ModernDialog。 问题是 link 只有 Source 选项,我不想导航到另一个页面(只想弹出一个 ModernDialog)。 我发现了这个:How to open a new window click on a menu link in Modern UI wpf? 但它只会在第一次点击时弹出 window,它还会导航到第一个标签页(我的意思是我查看的页面的 "parent")。

有人有想法吗?可能吗?

这是我的代码(相关部分),我说的是 "connect" link:

 <mui:ModernWindow.TitleLinks>
        <mui:Link x:Name="connect" DisplayName="connect"/>
        <mui:Link DisplayName="settings" Source="/Pages/SettingsPage.xaml" />
        <mui:Link DisplayName="help" Source="https://github.com" />
    </mui:ModernWindow.TitleLinks>

我会采取不同的方法。

加载 MainWindow 后,找到 ModernFrame 并挂接 Navigating 事件。

在导航事件处理程序中,检查源是否以 "dialog:" 开头(任意字符串,使用任何你想要的)然后显示对话框并取消导航。

link 的源设置为 "dialog:Test" 以表明我想显示 "Test" 对话框。

MainWindow.xaml

<mui:ModernWindow x:Class="WpfApp17.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mui="http://firstfloorsoftware.com/ModernUI"
        xmlns:local="clr-namespace:WpfApp17"
        mc:Ignorable="d"
        Loaded="ModernWindow_Loaded"
        ContentSource="/UserControl1.xaml"
        Title="MainWindow" Height="350" Width="525">
    <mui:ModernWindow.TitleLinks>
        <mui:Link x:Name="connect" DisplayName="connect" Source="dialog:Test" />
    </mui:ModernWindow.TitleLinks>
</mui:ModernWindow>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using FirstFloor.ModernUI.Windows.Controls;

namespace WpfApp17
{
    public partial class MainWindow : ModernWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ModernWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var frame = VisualTreeHelperFindChildren<ModernFrame>(this).FirstOrDefault();
            if (frame != null)
                frame.Navigating += Frame_Navigating;
        }

        private void Frame_Navigating(object sender, FirstFloor.ModernUI.Windows.Navigation.NavigatingCancelEventArgs e)
        {
            string dialog = "dialog:";
            if (e.Source.OriginalString.StartsWith(dialog))
            {
                // Show dialog
                var dialogName = e.Source.OriginalString.Remove(0, dialog.Length);
                MessageBox.Show($"Show Dialog '{dialogName}'");
                e.Cancel = true;
            }
        }

        public static List<T> VisualTreeHelperFindChildren<T>(DependencyObject parent) where T : class
        {
            List<T> list = new List<T>();

            if (parent != null)
            {
                int count = VisualTreeHelper.GetChildrenCount(parent);
                for (int i = 0; i < count; i++)
                {
                    // Get object at index i
                    DependencyObject dobj = VisualTreeHelper.GetChild(parent, i);

                    if (dobj is T)
                    {
                        list.Add(dobj as T);
                    }

                    // Loop through its children
                    list.AddRange(VisualTreeHelperFindChildren<T>(dobj));
                }
            }
            return list;
        }

    }
}

顺便说一句 - UserControl1.xaml 上面只有一个文本块,没有其他内容。我添加它以便屏幕上显示一些内容。

您可以覆盖 ModernWindowOnApplyTemplate() 方法并添加一个 NavigateLink 命令绑定到 ModernFrame。如果不设置 Link:

Source 属性,命令参数将是 null
public partial class MainWindow : ModernWindow
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        var frame = Template.FindName("ContentFrame", this) as ModernFrame;
        if(frame != null)
            frame.CommandBindings.Add(new CommandBinding(FirstFloor.ModernUI.Windows.Navigation.LinkCommands.NavigateLink, OnNavigateLinkExecuted));
    }

    private void OnNavigateLinkExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        if(e.Parameter == null)
        {
            ModernDialog dialog = new ModernDialog();
            dialog.ShowDialog();
        }
        else
        {
            OnNavigateLink(sender, e);
        }
    }

    private void OnNavigateLink(object sender, ExecutedRoutedEventArgs e)
    {
        if (LinkNavigator != null)
        {
            Uri uri;
            string parameter;
            string targetName;

            if (FirstFloor.ModernUI.Windows.Navigation.NavigationHelper.TryParseUriWithParameters(e.Parameter, out uri, out parameter, out targetName))
                LinkNavigator.Navigate(uri, e.Source as FrameworkElement, parameter);
        }
    }
}

XAML:

<mui:ModernWindow.TitleLinks>
    <mui:Link x:Name="connect" DisplayName="connect"/>
    <mui:Link DisplayName="settings" Source="/Pages/SettingsPage.xaml" />
    <mui:Link DisplayName="help" Source="https://github.com" />
</mui:ModernWindow.TitleLinks>