如何在 modernUI WPF 应用程序中嵌套 ModernMenu?
How to nest a ModernMenu in a modernUI WPF application?
我正在使用 ModernUI 框架创建 WPF 应用程序,但在我的 MainWindow 中嵌套 ModernMenu 控件时遇到问题 class。这是我最初为我的主窗口设置的内容:
<mui:ModernWindow x:Class="MyApp.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:MyApp"
mc:Ignorable="d"
Title="MyApp" IsTitleVisible="True" Height="350" Width="525" WindowState="Maximized" ContentSource="/Views/SourcePage1.xaml">
<mui:ModernWindow.MenuLinkGroups >
<mui:LinkGroup x:Name="sourceGroup" DisplayName="Source">
<mui:LinkGroup.Links>
<mui:Link x:Name="sourceLink1" DisplayName="File" Source="/Views/SourcePage1.xaml"/>
<mui:Link x:Name="sourceLink2" DisplayName="Instrumentation" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
</mui:ModernWindow.MenuLinkGroups>
在 "SourcePage1.xaml" 中,我尝试添加第二个子菜单(ModernMenu 的一个实例):
<UserControl x:Class="MyApp.Views.SourcePage1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
xmlns:local="clr-namespace:MyApp.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="mainGrid" Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="initialSpacer" Grid.Column="0" Background="Transparent" BorderBrush="DimGray" BorderThickness="2">
<Grid>
<Label Content="Ready" FontSize="40" Foreground="DimGray" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<GridSplitter Grid.Column="1" Width="4" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
<mui:ModernMenu Grid.Column="2">
<mui:ModernMenu.LinkGroups>
<mui:LinkGroup DisplayName="Catagory1">
<mui:LinkGroup.Links>
<mui:Link x:Name="catagory1Link" DisplayName="name1" Source="/Views/SettingsPage.xaml"/>
<mui:Link DisplayName="insert" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
<mui:LinkGroup DisplayName="Catagory2">
<mui:LinkGroup.Links>
<mui:Link DisplayName="name1" />
<mui:Link DisplayName="name2" />
<mui:Link DisplayName="name3" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
<mui:LinkGroup DisplayName="Catagory3">
<mui:LinkGroup.Links>
<mui:Link DisplayName="name1" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
</mui:ModernMenu.LinkGroups>
</mui:ModernMenu>
</Grid>
其中 "SettingsPage.xaml" 仅用于测试:
<UserControl x:Class="MyApp.Views.SettingsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
xmlns:local="clr-namespace:MyApp.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="mainGrid" Margin="0,10,0,0">
<Label Content = "Hi there!"/>
</Grid>
MainWindows 的现代菜单出现并且运行良好。同样,"SourcePage1.xaml" 上的 ModernMenu 也显示得很好,但我似乎无法为其分配任何源内容。当我单击任何已分配内容的链接(如 "catagory1Link")时,什么也没有出现。这里可能是什么问题?我不能像这样嵌套菜单吗?
ModernMenu 不会像您所说的那样自动导航框架。您可以改用 ModernTab,但它会设置另一个 ModernFrame 并且该框架是 links 设置源的框架。
ModernMenu 确实有一个 SelectedLink DependencyProperty。如果将它绑定到用户控件上的 属性,则可以检测到 link 单击并自行导航框架。
SourcePage1.xaml
<mui:ModernMenu Grid.Column="1" SelectedLink="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=MenuSelectedLink, Mode=OneWayToSource}">
SourcePage1.xaml.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
using FirstFloor.ModernUI.Presentation;
namespace WpfApp17
{
public partial class SourcePage1 : UserControl, INotifyPropertyChanged
{
public SourcePage1()
{
InitializeComponent();
}
#region Property Link MenuSelectedLink
private Link _MenuSelectedLink;
public Link MenuSelectedLink { get { return _MenuSelectedLink; } set { SetProperty(ref _MenuSelectedLink, value); OnMenuSelectedLinkChanged(); } }
#endregion
private void OnMenuSelectedLinkChanged()
{
if (MenuSelectedLink == null || MenuSelectedLink.Source == null)
return;
// Navigate the frame to the source.
var frame = FirstFloor.ModernUI.Windows.Navigation.NavigationHelper.FindFrame(null, this);
if (frame != null)
{
if (frame.Source != MenuSelectedLink.Source)
frame.Source = MenuSelectedLink.Source;
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null)
{
if (Equals(field, value))
{
return false;
}
field = value;
this.OnPropertyChanged(name);
return true;
}
protected void OnPropertyChanged([CallerMemberName]string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
#endregion
}
}
J.H.的解决方案是正确的,我已将其标记为正确。我只做了一些改动以获得我正在寻找的行为:我创建了一个新的 UserControl,它只包含网格第一行中的 "ModernMenu" 对象和第二行中的 "ModernFrame" 对象。该框架名为 "pageFrame"。然后,当菜单 link 在这个新的 UserControls 代码隐藏文件中更改时,我直接将内容添加到 pageFrame:
private void OnMenuSelectedLinkChanged()
{
if (MenuSelectedLink == null || MenuSelectedLink.Source == null)
return;
// Navigate the frame to the source.
pageFrame.Source = MenuSelectedLink.Source;
}
我正在使用 ModernUI 框架创建 WPF 应用程序,但在我的 MainWindow 中嵌套 ModernMenu 控件时遇到问题 class。这是我最初为我的主窗口设置的内容:
<mui:ModernWindow x:Class="MyApp.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:MyApp"
mc:Ignorable="d"
Title="MyApp" IsTitleVisible="True" Height="350" Width="525" WindowState="Maximized" ContentSource="/Views/SourcePage1.xaml">
<mui:ModernWindow.MenuLinkGroups >
<mui:LinkGroup x:Name="sourceGroup" DisplayName="Source">
<mui:LinkGroup.Links>
<mui:Link x:Name="sourceLink1" DisplayName="File" Source="/Views/SourcePage1.xaml"/>
<mui:Link x:Name="sourceLink2" DisplayName="Instrumentation" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
</mui:ModernWindow.MenuLinkGroups>
在 "SourcePage1.xaml" 中,我尝试添加第二个子菜单(ModernMenu 的一个实例):
<UserControl x:Class="MyApp.Views.SourcePage1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
xmlns:local="clr-namespace:MyApp.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="mainGrid" Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="initialSpacer" Grid.Column="0" Background="Transparent" BorderBrush="DimGray" BorderThickness="2">
<Grid>
<Label Content="Ready" FontSize="40" Foreground="DimGray" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<GridSplitter Grid.Column="1" Width="4" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
<mui:ModernMenu Grid.Column="2">
<mui:ModernMenu.LinkGroups>
<mui:LinkGroup DisplayName="Catagory1">
<mui:LinkGroup.Links>
<mui:Link x:Name="catagory1Link" DisplayName="name1" Source="/Views/SettingsPage.xaml"/>
<mui:Link DisplayName="insert" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
<mui:LinkGroup DisplayName="Catagory2">
<mui:LinkGroup.Links>
<mui:Link DisplayName="name1" />
<mui:Link DisplayName="name2" />
<mui:Link DisplayName="name3" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
<mui:LinkGroup DisplayName="Catagory3">
<mui:LinkGroup.Links>
<mui:Link DisplayName="name1" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
</mui:ModernMenu.LinkGroups>
</mui:ModernMenu>
</Grid>
其中 "SettingsPage.xaml" 仅用于测试:
<UserControl x:Class="MyApp.Views.SettingsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
xmlns:local="clr-namespace:MyApp.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="mainGrid" Margin="0,10,0,0">
<Label Content = "Hi there!"/>
</Grid>
MainWindows 的现代菜单出现并且运行良好。同样,"SourcePage1.xaml" 上的 ModernMenu 也显示得很好,但我似乎无法为其分配任何源内容。当我单击任何已分配内容的链接(如 "catagory1Link")时,什么也没有出现。这里可能是什么问题?我不能像这样嵌套菜单吗?
ModernMenu 不会像您所说的那样自动导航框架。您可以改用 ModernTab,但它会设置另一个 ModernFrame 并且该框架是 links 设置源的框架。
ModernMenu 确实有一个 SelectedLink DependencyProperty。如果将它绑定到用户控件上的 属性,则可以检测到 link 单击并自行导航框架。
SourcePage1.xaml
<mui:ModernMenu Grid.Column="1" SelectedLink="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=MenuSelectedLink, Mode=OneWayToSource}">
SourcePage1.xaml.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
using FirstFloor.ModernUI.Presentation;
namespace WpfApp17
{
public partial class SourcePage1 : UserControl, INotifyPropertyChanged
{
public SourcePage1()
{
InitializeComponent();
}
#region Property Link MenuSelectedLink
private Link _MenuSelectedLink;
public Link MenuSelectedLink { get { return _MenuSelectedLink; } set { SetProperty(ref _MenuSelectedLink, value); OnMenuSelectedLinkChanged(); } }
#endregion
private void OnMenuSelectedLinkChanged()
{
if (MenuSelectedLink == null || MenuSelectedLink.Source == null)
return;
// Navigate the frame to the source.
var frame = FirstFloor.ModernUI.Windows.Navigation.NavigationHelper.FindFrame(null, this);
if (frame != null)
{
if (frame.Source != MenuSelectedLink.Source)
frame.Source = MenuSelectedLink.Source;
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null)
{
if (Equals(field, value))
{
return false;
}
field = value;
this.OnPropertyChanged(name);
return true;
}
protected void OnPropertyChanged([CallerMemberName]string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
#endregion
}
}
J.H.的解决方案是正确的,我已将其标记为正确。我只做了一些改动以获得我正在寻找的行为:我创建了一个新的 UserControl,它只包含网格第一行中的 "ModernMenu" 对象和第二行中的 "ModernFrame" 对象。该框架名为 "pageFrame"。然后,当菜单 link 在这个新的 UserControls 代码隐藏文件中更改时,我直接将内容添加到 pageFrame:
private void OnMenuSelectedLinkChanged()
{
if (MenuSelectedLink == null || MenuSelectedLink.Source == null)
return;
// Navigate the frame to the source.
pageFrame.Source = MenuSelectedLink.Source;
}