lepoco / lepoco/wpfui

NavigationItem: can't figure out how to set initial page

Open
#737 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C#
Stars
9.6k
Forks
1k
PR merge metrics
No merged PRs in 30d

Description

Describe the bug

I have a bunch of navigation items:

<wpfui:NavigationFluent
    x:Name="Navigation"
    Frame="{Binding ElementName=ContentFrame}"
    SelectedPageIndex="0">
    <wpfui:NavigationFluent.Items>
        <wpfui:NavigationItem
            Content="Title 1"
            Icon="Folder20"
            IconSize="20"
            PageType="{x:Type local:View1}" />
        <wpfui:NavigationItem
            Content="Title 2"
            Icon="Folder20"
            IconSize="20"
            PageType="{x:Type local:View2}" />
        <wpfui:NavigationItem
            Content="Title 2"
            Icon="Folder20"
            IconSize="20"
            PageType="{x:Type local:View3}" />
    </wpfui:NavigationFluent.Items>
</wpfui:NavigationFluent>

The navigation items work; if I click something in the sidebar, a page gets instantiated and shown, even with animation. However, I have SelectedPageIndex="0", so the first page should automatically show, and it does not. The pages do correctly get tags (PageTag is set), so that doesn't appear to be the issue.

I surmise from the code that there are two problems here:

  1. UpdateServiceItems gets called too soon, so the NavigationService iterates over an empty collection.
  2. It also doesn't initially have _frame set.

Both lead to it ultimately returning false.

I was able to hack around it with reflection as follows:

        var navigationBaseType = typeof(NavigationBase);
        _ = navigationBaseType.GetMethod("UpdateServiceItems", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(Navigation, null);
        var navigationService = navigationBaseType.GetField("_navigationService", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(Navigation);
        navigationService.GetType().GetField("_frame", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(navigationService, ContentFrame);

        _ = Navigation.Navigate("view1");

Now, View1 gets animated into place as soon as the window opens.

To Reproduce
Expected behavior

NavigationFluent should be sufficiently initialized such that either SelectedPageIndex or calling Navigate() in Loaded does something meaningful.

Screenshots

No response

OS version

Windows 11 23521

.NET version

.NET Framework 4.7.2

WPF-UI NuGet version

2.1.0

Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Trace NavigationFluent initialization through NavigationBase.UpdateServiceItems and NavigationService, focusing on when the item collection and _frame become available. Verify the behavior of SelectedPageIndex and Navigate() from Loaded using the reported XAML setup. Done means the initial page is shown without reflection, and navigation still works when items and the frame are initialized.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.