C# WinUI 3 Desktop 如何向应用程序实例公开接口?

发布于 2025-01-11 03:48:15 字数 4885 浏览 0 评论 0原文

尝试使用此解决方案通过代码隐藏实现 NavigationView 导航,我发现:https://xamlbrewer.wordpress.com/2021/07/06/navigating-in-a-winui-3-desktop-application/

我收到此编译错误:

输入图像描述这里

错误是说我应该 'cast' m_window;该示例未投射。为什么我需要投射?

我创建了一个界面:(INavigation.cs)

using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MetricReporting.Interfaces
{
    interface INavigation
    {
        NavigationViewItem GetCurrentNavigationViewItem();

        List<NavigationViewItem> GetNavigationViewItems();

        List<NavigationViewItem> GetNavigationViewItems(Type type);

        List<NavigationViewItem> GetNavigationViewItems(Type type, string title);

        void SetCurrentNavigationViewItem(NavigationViewItem item);
    }
}

我创建了主窗口的部分类(MainWindow.xaml.Navigation.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MetricReporting
{
    public partial class MainWindow : INavigation
    {
        public NavigationViewItem GetCurrentNavigationViewItem()
        {
            return NavigationView.SelectedItem as NavigationViewItem;
        }

        public List<NavigationViewItem> GetNavigationViewItems()
        {
            var result = new List<NavigationViewItem>();
            var items = NavigationView.MenuItems.Select(i => (NavigationViewItem)i).ToList();
            items.AddRange(NavigationView.FooterMenuItems.Select(i => (NavigationViewItem)i));
            result.AddRange(items);
 
            foreach (NavigationViewItem mainItem in items)
            {
                result.AddRange(mainItem.MenuItems.Select(i => (NavigationViewItem)i));
            }
 
            return result;
        }
 
        public List<NavigationViewItem> GetNavigationViewItems(Type type)
        {
            return GetNavigationViewItems().Where(i => i.Tag.ToString() == type.FullName).ToList();
        }
 
        public List<NavigationViewItem> GetNavigationViewItems(Type type, string title)
        {
            return GetNavigationViewItems(type).Where(ni => ni.Content.ToString() == title).ToList();
        }

        public void SetCurrentNavigationViewItem(NavigationViewItem item)
        {
            if (item == null)
            {
                return;
            }

            if (item.Tag == null)
            {
                return;
            }

            MasterContentFrame.Navigate(
            Type.GetType(item.Tag.ToString()),
            item.Content);
            NavigationView.Header = item.Content;
            NavigationView.SelectedItem = item;
        }
    }
}

我将此行添加到我的 App.xaml.cs 文件中:

public INavigation Navigation => m_window;

它对文章中的行进行建模:

private Shell shell;
 
public INavigation Navigation => shell;
         
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    shell = new Shell();
    shell.Activate();
}

我应该能够像这样使用导航服务:

All parts of the code base can now easily access the lightweight Navigation Service:

(Application.Current as App).Navigation

为了清楚起见,这是我的 App.xaml.cs

using MetricReporting.Interfaces;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Navigation;
    
namespace MetricReporting
{
    public partial class App : Application
    {
        /// <summary>
        /// Initializes the singleton application object.  This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public App()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when the application is launched normally by the end user.  Other entry points
        /// will be used such as when the application is launched to open a specific file.
        /// </summary>
        /// <param name="args">Details about the launch request and process.</param>
        /// 

        protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
        {
            m_window = new MainWindow();
            m_window.Activate();
        }

        private Window m_window;

        public INavigation Navigation => m_window;   //Compiler does not like this
        //public INavigation Navigation => m_window;   Compiler does not like this
    }
}

Attempting to implement NavigationView navigation via code-behind using this solution I found: https://xamlbrewer.wordpress.com/2021/07/06/navigating-in-a-winui-3-desktop-application/

I get this compile error:

enter image description here

The error is saying I should 'cast' m_window; The example did not cast. Why do I need to cast?

I created an interface: (INavigation.cs)

using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MetricReporting.Interfaces
{
    interface INavigation
    {
        NavigationViewItem GetCurrentNavigationViewItem();

        List<NavigationViewItem> GetNavigationViewItems();

        List<NavigationViewItem> GetNavigationViewItems(Type type);

        List<NavigationViewItem> GetNavigationViewItems(Type type, string title);

        void SetCurrentNavigationViewItem(NavigationViewItem item);
    }
}

I created a partial class of my main window (MainWindow.xaml.Navigation.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MetricReporting
{
    public partial class MainWindow : INavigation
    {
        public NavigationViewItem GetCurrentNavigationViewItem()
        {
            return NavigationView.SelectedItem as NavigationViewItem;
        }

        public List<NavigationViewItem> GetNavigationViewItems()
        {
            var result = new List<NavigationViewItem>();
            var items = NavigationView.MenuItems.Select(i => (NavigationViewItem)i).ToList();
            items.AddRange(NavigationView.FooterMenuItems.Select(i => (NavigationViewItem)i));
            result.AddRange(items);
 
            foreach (NavigationViewItem mainItem in items)
            {
                result.AddRange(mainItem.MenuItems.Select(i => (NavigationViewItem)i));
            }
 
            return result;
        }
 
        public List<NavigationViewItem> GetNavigationViewItems(Type type)
        {
            return GetNavigationViewItems().Where(i => i.Tag.ToString() == type.FullName).ToList();
        }
 
        public List<NavigationViewItem> GetNavigationViewItems(Type type, string title)
        {
            return GetNavigationViewItems(type).Where(ni => ni.Content.ToString() == title).ToList();
        }

        public void SetCurrentNavigationViewItem(NavigationViewItem item)
        {
            if (item == null)
            {
                return;
            }

            if (item.Tag == null)
            {
                return;
            }

            MasterContentFrame.Navigate(
            Type.GetType(item.Tag.ToString()),
            item.Content);
            NavigationView.Header = item.Content;
            NavigationView.SelectedItem = item;
        }
    }
}

I am adding this line to my App.xaml.cs file:

public INavigation Navigation => m_window;

It models the line from the article:

private Shell shell;
 
public INavigation Navigation => shell;
         
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    shell = new Shell();
    shell.Activate();
}

I should be able to use the navigation service like this:

All parts of the code base can now easily access the lightweight Navigation Service:

(Application.Current as App).Navigation

For clarity, here is my App.xaml.cs

using MetricReporting.Interfaces;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Navigation;
    
namespace MetricReporting
{
    public partial class App : Application
    {
        /// <summary>
        /// Initializes the singleton application object.  This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public App()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when the application is launched normally by the end user.  Other entry points
        /// will be used such as when the application is launched to open a specific file.
        /// </summary>
        /// <param name="args">Details about the launch request and process.</param>
        /// 

        protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
        {
            m_window = new MainWindow();
            m_window.Activate();
        }

        private Window m_window;

        public INavigation Navigation => m_window;   //Compiler does not like this
        //public INavigation Navigation => m_window;   Compiler does not like this
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浮萍、无处依 2025-01-18 03:48:15

m_window 是一个 Window...所以它可以是任何 Window 而不一定是您的 MainWindow< /code>,或任何实现 INavigation 的内容。这就是构建的所有信息。

你可以用以下方法修复它:

private MainWindow m_window;

m_window is a Window...so it could be any Window and not necessarily your MainWindow, or anything that implements INavigation. That's all of the information that build has.

You could fix it with:

private MainWindow m_window;
最冷一天 2025-01-18 03:48:15

您需要将 m_window 转换为 INavigation 以便编译代码:

public INavigation Navigation => m_window as INavigation;

或者将 m_window 字段定义为 INavigation直接按照@rfmodulator (+1) 的建议:

private MainWindow m_window;

You need to cast m_window to an INavigation for your code to compile:

public INavigation Navigation => m_window as INavigation;

Or define the m_window field as an INavigation directly as suggested by @rfmodulator (+1):

private MainWindow m_window;
魔法少女 2025-01-18 03:48:15

我运行了相同的代码,错误是隐式继承了错误的接口。

在下面的行中,接口 INavigation 来自命名空间:namespace Microsoft.EntityFrameworkCore.Metadata

public INavigation Navigation => m_window;

只需直接指定您正在使用哪个接口,例如,如果您想使用您的实现:

public MetricReporting.Services.Interfaces.INavigation Navigation => m_window;

或更改接口的名称,例如IMainWindowsNavigation

I ran the same code, and the error is that the wrong interface is implicitly inherited.

In the following line, interface INavigation is from namespace: namespace Microsoft.EntityFrameworkCore.Metadata.

public INavigation Navigation => m_window;

Just specify directly which interface are you using, for example if you want to use your implementation:

public MetricReporting.Services.Interfaces.INavigation Navigation => m_window;

or change the name of your interface, e.g. IMainWindowsNavigation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文