LennyL
LennyL

Reputation: 333

C# WinUI 3 Get CS0053 error Inconsistent accessibility: property type 'INavigation' is less accessible than property 'App.Navigation'

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 don't know what I am doing wrong. :-(. I am new to C#, WinUI. Where is 'App.Navigation'?????

enter image description here

Outline of solution:

  1. All navigation-related code is implemented in a partial class of the Shell window,
  2. encapsulated in an interface that is
  3. exposed via the App instance to
  4. the different XAML pages.

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 modified the App.xaml.cs:

using MetricReporting.Interfaces;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.UI.Xaml.Shapes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace MetricReporting
{
    /// <summary>
    /// Provides application-specific behavior to supplement the default Application class.
    /// </summary>
    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>
        /// 

        // ** this is what I added per the web article ** 
        public INavigation Navigation => (INavigation)m_window;
        //public INavigation Navigation => m_window;   Compiler does not like this

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

        private Window m_window;
    }
}

Here is my MainWindow.xaml.cs in case it helps. The NavigationView code works well, I can navigate to all of the pages via navigation menu UI. :-). I just need to be able to navigate from the code behind. I am so sorry for the verbose post.

    using MetricReporting.Pages;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Diagnostics;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace MetricReporting
{
    /// <summary>
    /// An empty window that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
            this.Title = "EMB Metric Reporting Tool";
            MasterContentFrame.Navigate(typeof(pageHome));
            MasterNavigation.Header = "Home";
        }

        private void MasterNavigation_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
        {
            if (args.IsSettingsInvoked)
            {
                MasterContentFrame.Navigate(typeof(pageSettings));
            }
            else
            {
                // find NavigationViewItem with Content that equals InvokedItem
                NavigationViewItem item = sender.MenuItems.OfType<NavigationViewItem>().First(x => (string)x.Content == (string)args.InvokedItem);
                NavView_Navigate(item);
            }
        }

        private void NavView_Navigate(NavigationViewItem item)
        {
            switch (item.Tag)
            {
                case "home":
                    MasterContentFrame.Navigate(typeof(pageHome));
                    MasterNavigation.Header = item.Content;
                    break;

                case "datacollection":
                    MasterContentFrame.Navigate(typeof(pageDataCollection));
                    MasterNavigation.Header = item.Content;
                    break;

                case "collectdata":
                    MasterContentFrame.Navigate(typeof(PageCollectMetricData));
                    MasterNavigation.Header = item.Content;
                    break;

                case "goals":
                    MasterContentFrame.Navigate(typeof(pageGoals));
                    MasterNavigation.Header = item.Content;
                    break;

                case "approvals":
                    MasterContentFrame.Navigate(typeof(pageComments));
                    MasterNavigation.Header = item.Content;
                    break;

                case "reports":
                    MasterContentFrame.Navigate(typeof(pageReports));
                    MasterNavigation.Header = item.Content;
                    break;

                case "admin":
                    MasterContentFrame.Navigate(typeof(pageAdmin));
                    MasterNavigation.Header = item.Content;
                    break;

                case "metricstaging":
                    MasterContentFrame.Navigate(typeof(pageMetricStaging));
                    MasterNavigation.Header = item.Content;
                    break;

                case "refmetricmain":
                    MasterContentFrame.Navigate(typeof(pageRefMetricMain));
                    MasterNavigation.Header = item.Content;
                    break;
            }
        }

        private async void DisplayCommentDialog()
        {
            ContentDialog testDialog = new ContentDialog()
            {
                Title = "Main Window Loaded",
                Content = "Main Window Loaded",
                CloseButtonText = "Ok"
            };
            await testDialog.ShowAsync();
        }
    }
}

Upvotes: 0

Views: 521

Answers (1)

mm8
mm8

Reputation: 169340

The error message tells you that INavigation must be public:

public interface INavigation
{
    NavigationViewItem GetCurrentNavigationViewItem();

    List<NavigationViewItem> GetNavigationViewItems();

    List<NavigationViewItem> GetNavigationViewItems(Type type);

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

    void SetCurrentNavigationViewItem(NavigationViewItem item);
}

If you define it as just interface INavigation { ... } (without the public keyword) it's internal by default and cannot be used as the return type of a public member.

So change interface INavigation to public interface INavigation in your code.

Upvotes: 2

Related Questions