Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flicker when switching between nested TabViews #465

Open
brads55 opened this issue Aug 23, 2023 · 5 comments
Open

Flicker when switching between nested TabViews #465

brads55 opened this issue Aug 23, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@brads55
Copy link

brads55 commented Aug 23, 2023

Describe the bug
When using a nest of TabViews, switching between the top level tabs causes the tab content being switched to to flicker, as though there is a blank frame before the child content is shown.

Desktop/Platform

  • OS: MacOS, but I believe this also happens on Windows.
  • FluentAvalonia Version: 2.0.1
  • Avalonia Version: 11.0.2

Additional context
This only seems to happen if the tab content being shown at the top level is a view model rather than a direct view, and the sub view that represents this view model contains another TabView i.e.:

MainView:

    <ui:TabView>
        <ui:TabViewItem Header="Header">
            <vm:SubViewModel />
        </ui:TabViewItem>
        <ui:TabViewItem Header="Header">
            <vm:SubViewModel />
        </ui:TabViewItem>
    </ui:TabView>

SubView:

    <ui:TabView>
        <ui:TabViewItem Header="Header">
            <Grid Background="DarkRed" MinHeight="800" />
        </ui:TabViewItem>
    </ui:TabView>

If the MainView TabViewItem content is another view, or the SubView TabView is placed directly in MainView, the issue doesn't seem to occur. I've created a very simple reproducer project here: https://github.com/brads55/AvTest.

@brads55 brads55 added the bug Something isn't working label Aug 23, 2023
@amwx
Copy link
Owner

amwx commented Sep 10, 2023

I was able to get rid of the flicker by removing the MinHeight="800", which also made the inner TabView show correctly. 800 is kind of an non-sensible value for height, considering 1080 is probably the max most people have, and that's before display scaling considerations.
Also note, TabView has a default VerticalAlignment of Top, it's probably better to set VerticalAlignment="Stretch" than a MinWidth.

I'm also testing on a much simpler case of just straight nested TabViews which should be the same thing, in principle:

<ui:TabView VerticalAlignment="Stretch">
    <ui:TabViewItem Header="Header1">
        <ui:TabView VerticalAlignment="Stretch">
            <ui:TabViewItem Header="SubHeader">
                <Grid Background="DarkRed" />
            </ui:TabViewItem>
        </ui:TabView>
    </ui:TabViewItem>
    <ui:TabViewItem Header="Header2">
        <ui:TabView>
            <ui:TabViewItem Header="SubHeader2">
                <Grid Background="DarkRed" />
            </ui:TabViewItem>
        </ui:TabView>
    </ui:TabViewItem>
</ui:TabView>

@brads55
Copy link
Author

brads55 commented Sep 11, 2023

The MinHeight was just there to ensure the control was visible to see the flicker, but yes, using VerticalAlignment=Stretch is more sensible. Replacing that, I still see the flicker however.

When I was testing this, I noted that using a nested viewmodel like I have, rather than all in one xaml file like you have, made the flicker much more reproducible and apparent. I think the flicker may still be there with it all in one xaml file, however it only seems to happen on the first tab switch, after that it seems to go away. Which I guess suggests this may be something to do with view construction?

@amwx
Copy link
Owner

amwx commented Sep 11, 2023

I'd highly recommend not using the ViewLocator approach to templates. I thought that was supposed to be removed from the default Avalonia template.

Fixing your MainWindow.axaml file like below, I no longer see the flickering:

<Window.DataTemplates>
    <DataTemplate DataType="vm:SubViewModel">
        <views:SubView />
    </DataTemplate>
</Window.DataTemplates>

<ui:TabView x:Name="MainTab" VerticalAlignment="Stretch">
    <ui:TabViewItem Header="Header">
        <vm:SubViewModel />
    </ui:TabViewItem>
    <ui:TabViewItem Header="Header">
        <vm:SubViewModel />
    </ui:TabViewItem>
</ui:TabView>

@brads55
Copy link
Author

brads55 commented Sep 12, 2023

Hm ok, using that approach does appear to fix the flicker, however I'm still getting odd behaviour when nesting TabViews.

I've updated the linked repository to extend the testcase to show two more issues I'm hitting:

  • When switching top level tabs, the lower level tabs seem to collapse and expand, i.e. you can visually see SubView changing between 1 and 3 tabs.
  • The SelectedItem binding of the child TabView doesn't seem to persist when changing top level tab, i.e. you end up with no selected tab in SubView when changing top level tab. (I think SelectedIndex also has similar problems).

@brads55
Copy link
Author

brads55 commented May 4, 2024

I've had more of a dig into this and I don't believe this has anything to do with nesting TabViews, it's more about the initial state of the TabView. When a TabView is created it is rendered before the DataContext applied to it has properly taken effect. This manifests itself it two ways:

Upon creating a brand new TabView with a DataContext applied at time of construction, the tab content presenter is displayed empty before the real contents get applied, this is what is causing the flicker I reported. (The ViewLocator was not recycling views).

When applying a different DataContext to an existing TabView, the TabListView seems to update late which results in visually being able to see TabListView contents changing, as well as the selected item logic breaking as it tries to update the selected item prior to the TabListView items changing. This is what I observe with the changes you suggested. (The DataTemplate does recycle views).

I've updated the testcase at https://github.com/brads55/AvTest to better demonstrate what is going on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants