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 上面只有一个文本块,没有其他内容。我添加它以便屏幕上显示一些内容。
您可以覆盖 ModernWindow
的 OnApplyTemplate()
方法并添加一个 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>
我正在使用 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 上面只有一个文本块,没有其他内容。我添加它以便屏幕上显示一些内容。
您可以覆盖 ModernWindow
的 OnApplyTemplate()
方法并添加一个 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>