WPF 如何允许我的 ControlTemplate 使用现有的 NavigationService?

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

我有一个

ControlTemplate
的菜单,我想将其用于我的所有页面。
ControlTemplate
的函数调用需要使用属于我的
NavigationService
NavigationWindow
。但是,我无法将
ControlTemplate
放入
NavigationWindow xaml
文件中,因为页面无法访问它。我如何允许我的
ControlTemplate
访问
NavigationService
,同时可以在我的页面中使用?

我的

NavigationWindow
位于
MainWindow.xaml

App.xaml.cs

namespace WPFApplication
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private void Menu_ModeAdvanced_Click(object sender, RoutedEventArgs e)
        {
            // Where I want to access the Navigation Service
        }
    }
}

应用程序.xaml

<Application x:Class="WPFApplication.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WPFApplication"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <!-- Page Design -->
            <Style TargetType="Page">
                <Setter Property="Foreground" Value="#FBF5F3" />
                <Setter Property="Background" Value="#363537" />
            </Style>
            
            <!-- Label Design-->
            <Style TargetType="Label">
                <Setter Property="Foreground" Value="#FBF5F3" />
            </Style>
        </ResourceDictionary>

        <!-- Menu Template-->
        <ControlTemplate x:Key="StandardMenu" TargetType="Menu">
            <Menu Height="20">
                <MenuItem Header="File" AllowDrop="True">
                    <MenuItem Header="Mode" AllowDrop="True">
                        <MenuItem Header="Advanced"/>
                    </MenuItem>
                </MenuItem>
            </Menu>
        </ControlTemplate>
    </Application.Resources>
</Application>

我尝试将

ControlTemplate
和相关代码放入位于
ResourceDictionary
类中的
NavigationWindow
中。但是,我无法在我的页面中将其用作静态资源。

c# wpf controltemplate navigationservice navigationwindow
1个回答
0
投票

只需获取

Window
的父级
MenuItem
即可。如果是
NavigationWindow
,您可以使用其 API 执行导航相关任务或使用其关联的
NavigationWindow.NavigationService
:

private void Menu_ModeAdvanced_Click(object sender, RoutedEventArgs e)
{
  FrameworkElement element = sender as FramwworkElement;
  NavigationWindow navigationWindow = null;
  while (mi.Parent is not null)
  {
    element = element.Parent as FrameworkElement;
    if (element is NavigationWindow window)
    {
      navigationWindow = window;
      break;
    }
  }

  // Navigate etc. using the NavigationWindow API
  navigationWindow?.Navigate(new Uri());
 
  // Navigate etc. using the NavigationService
  navigationWindow?.NavigationService.Navigate(new Uri());
}

但我建议在您的

NavigationWindow
中定义路由命令。
从设计角度来看,它更加清晰,因为导航细节对导航主机来说是私有的:

MainWindow.xaml.cs

partial class MainWindow : NavigationWindow
{
  public static RoutedCommand NavigateToPageCommand { get; }
    = new RoutedCommand(nameof(MainWindow.NavigateToPageCommand, typeof(MainWindow)); 

  private Dictionary<PageId, Uri> PageUriStore { get; }

  public MainWindow()
  {
    InitializeComponent();

    var navigateCommandBinding = new CommandBinding(
      MainWindow.NavigateToPageCommand,
      ExecutedNavigateToPageCommand,
      CanexecutedNavigateToPageCommand);
    this.CommandBindings.Add(navigateCommandBinding);

    this.PageUriStore = new Dictionary<PageId, Uri>
    {
      { PageId.SettingsPage, new Uri(...) },
    };
  }

  private void CanexecutedNavigateToPageCommand(object sender, ExecutedRoutedEventArgs e)
    => e.CanExecute = e.Parameter is PageId;

  private void CanexecutedNavigateToPageCommand(object sender, ExecutedRoutedEventArgs e)
  {
    var pageId = (PageId)e.Parameter;
    if (this.PageUriStore.TryGetValue(pageId, out Uri destinationUri))
    {
      this.Navigate(ddestinationUri);
    }
  }
}

应用程序.xaml

<MenuItem Header="Settings"
          Command="{x:Static MainWindow.NavigateToPageCommand}"
          CommandParameter="{x:Static PageId.SettingsPage}" />

PageId.cs

enum PageId
{
  Default = 0,
  OverviewPage,
  SettingsPage
}
© www.soinside.com 2019 - 2024. All rights reserved.