C# WinUI 3 Desktop 如何向应用程序实例公开接口?
尝试使用此解决方案通过代码隐藏实现 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:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
m_window
是一个Window
...所以它可以是任何Window
而不一定是您的MainWindow< /code>,或任何实现
INavigation
的内容。这就是构建的所有信息。你可以用以下方法修复它:
m_window
is aWindow
...so it could be anyWindow
and not necessarily yourMainWindow
, or anything that implementsINavigation
. That's all of the information that build has.You could fix it with:
您需要将
m_window
转换为INavigation
以便编译代码:或者将
m_window
字段定义为INavigation
直接按照@rfmodulator (+1) 的建议:You need to cast
m_window
to anINavigation
for your code to compile:Or define the
m_window
field as anINavigation
directly as suggested by @rfmodulator (+1):我运行了相同的代码,错误是隐式继承了错误的接口。
在下面的行中,接口
INavigation
来自命名空间:namespace Microsoft.EntityFrameworkCore.Metadata
。只需直接指定您正在使用哪个接口,例如,如果您想使用您的实现:
或更改接口的名称,例如
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
.Just specify directly which interface are you using, for example if you want to use your implementation:
or change the name of your interface, e.g.
IMainWindowsNavigation
.