Reputation: 333
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
}
}
Upvotes: 0
Views: 768
Reputation: 1
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
.
Upvotes: 0
Reputation: 169340
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;
Upvotes: 0
Reputation: 3738
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;
Upvotes: 2