lepoco / wpfui

WPF UI provides the Fluent experience in your known and loved WPF framework. Intuitive design, themes, navigation and new immersive controls. All natively and effortlessly.
https://wpfui.lepo.co
MIT License
7.47k stars 725 forks source link

The active triggers in NavigationView are not displayed correctly #1059

Open BoyFaceGirl opened 5 months ago

BoyFaceGirl commented 5 months ago

Describe the bug

 I need to use it in conjunction with the Prism framework and do not require

the TargetPageType attribute. When deleting the TargetPageType attribute or leaving it null, there will be an error in displaying the selected style

PixPin_2024-04-18_08-48-08

To Reproduce

When deleting the TargetPageType attribute or leaving it null, there will be an error in displaying the selected style。

<ui:NavigationView
    x:Name="RootNavigation"
    Grid.Row="1"
    Margin="0"
    Padding="0"
    IsBackButtonVisible="Collapsed">
    <ui:NavigationView.AutoSuggestBox>
        <ui:AutoSuggestBox x:Name="AutoSuggestBox" PlaceholderText="Search">
            <ui:AutoSuggestBox.Icon>
                <ui:IconSourceElement>
                    <ui:SymbolIconSource Symbol="Search24" />
                </ui:IconSourceElement>
            </ui:AutoSuggestBox.Icon>
        </ui:AutoSuggestBox>
    </ui:NavigationView.AutoSuggestBox>
    <ui:NavigationView.Header>
        <ui:BreadcrumbBar
            Margin="42,32,0,0"
            FontSize="28"
            FontWeight="DemiBold" />
    </ui:NavigationView.Header>
    <ui:NavigationView.MenuItems>
        <ui:NavigationViewItem Content="Dashboard" NavigationCacheMode="Enabled">
            <ui:NavigationViewItem.Icon>
                <ui:SymbolIcon Symbol="Home24" />
            </ui:NavigationViewItem.Icon>
        </ui:NavigationViewItem>
        <ui:NavigationViewItem Content="Data" NavigationCacheMode="Enabled">
            <ui:NavigationViewItem.Icon>
                <ui:SymbolIcon Symbol="DataHistogram24" />
            </ui:NavigationViewItem.Icon>
        </ui:NavigationViewItem>
    </ui:NavigationView.MenuItems>
</ui:NavigationView>

Expected behavior

This issue occurs when the NavigationViewItem does not have the TargetPageType property set. Inference and IsActive trigger xaml style incorrect

Screenshots

error: PixPin_2024-04-18_08-48-08

success:

PixPin_2024-04-18_08-51-55

OS version

win11

.NET version

.net8

WPF-UI NuGet version

3.0.4

Additional context

No response

BoyFaceGirl commented 5 months ago

I have found a feasible solution by adding the following recursive method to NavigationViewItem. cs:

    private void ClearActiveStatus(IList menuitems, NavigationView navigationView)
    {
        foreach (var item in menuitems)
        {
            var nvaitem = item as NavigationViewItem;

            if (nvaitem != null)
            {
                if (nvaitem.IsActive)
                {
                    nvaitem.Deactivate(navigationView);
                }

                if (nvaitem.HasMenuItems)
                {
                    ClearActiveStatus(nvaitem.MenuItems, navigationView);
                }
            }
        }
    }

Then call within Onclick:

  var navigation = NavigationView.GetNavigationParent(this);
  if (navigation is not null)
  {
      IList menuitems = navigation.MenuItems;

      ClearActiveStatus(menuitems, navigation);

      Activate(navigation);
  }

The complete modification code is:

 protected override void OnClick()
    {
        if (NavigationView.GetNavigationParent(this) is not { } navigationView)
        {
            return;
        }

        var navigation = NavigationView.GetNavigationParent(this);
        if (navigation is not null)
        {
            IList menuitems = navigation.MenuItems;
            ClearActiveStatus(menuitems, navigation);
            Activate(navigation);
        }

        if (HasMenuItems && navigationView.IsPaneOpen)
        {
            SetCurrentValue(IsExpandedProperty, !IsExpanded);
        }

        if (TargetPageType is not null)
        {
            navigationView.OnNavigationViewItemClick(this);
        }

        base.OnClick();
    }

    private void ClearActiveStatus(IList menuitems, NavigationView navigationView)
    {
        foreach (var item in menuitems)
        {
            var navitem = item as NavigationViewItem;

            if (navitem != null)
            {
                if (navitem.IsActive)
                {
                    navitem.Deactivate(navigationView);
                }

                if (navitem.HasMenuItems)
                {
                    ClearActiveStatus(navitem.MenuItems, navigationView);
                }
            }
        }
    }

🚀Someone can help review this code for any issues, and it would be even better if they could also assist in submitting the merge.😀

textGamex commented 3 months ago

可以描述一下具体的使用场景吗?

BoyFaceGirl commented 3 months ago

可以描述一下具体的使用场景吗?

需要自定义navigateviewitem的click行为,在click事件内添加prism的路由导航,另外TargetPageType 不应该影响navigateview控件的样式行为吧,winui3就是如此,没有TargetPageType 或者 TargetPageType =null,但是navigateview控件本身的选中状态和样式是不受任何影响的

textGamex commented 3 months ago

可以描述一下具体的使用场景吗?

需要自定义navigateviewitem的click行为,在click事件内添加prism的路由导航,另外TargetPageType 不应该影响navigateview控件的样式行为吧,winui3就是如此,没有TargetPageType 或者 TargetPageType =null,但是navigateview控件本身的选中状态和样式是不受任何影响的

prism的路由导航不是需要内容控件吗,NavigateView没有可以充当内容控件的东西吧?

BoyFaceGirl commented 3 months ago

可以描述一下具体的使用场景吗?

需要自定义navigateviewitem的click行为,在click事件内添加prism的路由导航,另外TargetPageType 不应该影响navigateview控件的样式行为吧,winui3就是如此,没有TargetPageType 或者 TargetPageType =null,但是navigateview控件本身的选中状态和样式是不受任何影响的

prism的路由导航不是需要内容控件吗,NavigateView没有可以充当内容控件的东西吧?

prism的路由导航需要内容控件,但是内容控件具体显示哪些内容需要灵活控制, 我是用NavigateViewItem 的click事件 来切换 页面,NavigateViewItem 的tag属性绑定一些json之类的数据,通过click可灵活切换内容页面且可以传递一些值。有一些 NavigateViewItem 是通过插件的形式动态加载的。mvvmlight 说实话导航基本就就是摆设。

textGamex commented 3 months ago

研究了一下,这个代码有个小bug,在侧边栏展开时选中菜单项,然后关闭侧边栏,菜单项选中效果会消失.