Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove broken background of ListViewItem In UWP?

Tags:

c#

listview

uwp

enter image description here

I Created a Listview with some items. When I click at one, I'm navigating to new page. When I press back, l'm going back to the old page (Main menu page -> item page -> backing to main menu by Frame.GoBack()) and I see all last clicked items are having gray background. I tried to set background to transparent, it doesn't work.

On Desktop this problem doesn't exist, Background is black. I'm testing it at Windows 10 RS2 & Windows 10 Mobile last insider build at L640XL.

Listview:

<ListView Grid.Row="
          Name="LineSecondTrackListView"
          ItemsSource="{x:Bind _LineSecondTrackBusStops}"
          ContainerContentChanging="SetBusStopViewAttribute"
          ItemTemplate="{StaticResource BusStopListViewStyle}"
          SelectionMode="Single"
          SelectionChanged="LineTrackListView_SelectionChangedAsync">
              <ListView.ItemsPanel>
                  <ItemsPanelTemplate>
                      <ItemsWrapGrid HorizontalAlignment="Center"
                                     Orientation="Horizontal" 
                                     MaximumRowsOrColumns="1"/>
                  </ItemsPanelTemplate>
              </ListView.ItemsPanel>
</ListView>

How i'm backing:

public static void BackButtonPressed(object sender, BackRequestedEventArgs e)
{
    Frame mainAppFrame = MainFrameHelper.GetMainFrame();
    Type currentPageType = mainAppFrame.CurrentSourcePageType;
    bool goBack = IsGoBackFromPageAllowed(currentPageType);
    if (goBack)
    {
        mainAppFrame.GoBack();
        e.Handled = true;
        return;
    }
    App.Current.Exit();
}

private static bool IsGoBackFromPageAllowed(Type currentPageType)
{
    if (currentPageType == typeof(Pages.Lines.LinesViewPage))
        return true;
    if (currentPageType == typeof(Pages.Lines.LinePage))
        return true;
    if (currentPageType == typeof(Pages.Lines.LineBusStopPage))
        return true;
    return false;
}

How to avoid this effect?

Edit

I tried with

foreach (ListViewItem item in LineSecondTrackListView.Items) 
    VisualStateManager.GoToState(item, "Normal", false); //in the OnNavigatedTo 

and it doesnt work

edit2 In main menu page, when I clicked at button and went back, this effect stays. All pages are having NavigationCachePage=Required main menu

edit3

ButtonListGridView.InvalidateMeasure();
ButtonListGridView.UpdateLayout();
ButtonListGridView.InvalidateArrange();

any of these did not fix that.

like image 403
Niewidzialny Avatar asked Mar 23 '17 22:03

Niewidzialny


1 Answers

A few things you can try here. I believe the gray background you see is the PressedBackground of the ListViewItemPresenter.

It's most likely a timing bug in UWP that when an item in the ListView is selected/pressed down, the PressedBackground/PointerOverBackground shows, and at the same time the page 1 is being cached and cleared from the Frame which can then display page 2, but what should happen before caching is that the page 1 needs to complete the pointer up/exit action in order to clear the PressedBackground/PointerOverBackground color, which it fails to do so.

To test out if that's the color of the issue, all you need is to apply the following default Style to your the ItemContainerStyle of your ListView, and set PressedBackground="Transparent" or/and PointerOverBackground="Transparent".

<Style TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="12,0,12,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="ListViewItem">
      <ListViewItemPresenter
          ContentTransitions="{TemplateBinding ContentTransitions}"
          SelectionCheckMarkVisualEnabled="True"
          CheckBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
          CheckBoxBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
          DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}"
          DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}"
          FocusBorderBrush="{ThemeResource SystemControlForegroundAltHighBrush}"
          FocusSecondaryBorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}"
          PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"
          PointerOverBackground="Transparent"
          PointerOverForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}"
          SelectedBackground="{ThemeResource SystemControlHighlightListAccentLowBrush}"
          SelectedForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}"
          SelectedPointerOverBackground="{ThemeResource SystemControlHighlightListAccentMediumBrush}"
          PressedBackground="Transparent"
          SelectedPressedBackground="{ThemeResource SystemControlHighlightListAccentHighBrush}"
          DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
          DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
          ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
          HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
          VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
          ContentMargin="{TemplateBinding Padding}"
          CheckMode="Inline"/>
    </ControlTemplate>
  </Setter.Value>
</Setter>
</Style>

But even this might fix the issue, it removes a meaningful visual indication. So let's try something else -

In your LineTrackListView_SelectionChangedAsync method, instead of navigating right after the delay, you de-select the item first, give it the same amount of delay to complete the de-selecting action, and then do the navigation. You will need to have a flag to avoid this method to be re-called by updating the SelectedItem.

private bool _isWorking;

private async void LineTrackListView_SelectionChangedAsync(object sender, SelectionChangedEventArgs e)
{
    if (_isWorking)
    {
        return;
    }

    _isWorking = true;

    // Removed some of your code here.

    listView.SelectedItem = -1;
    await Task.Delay(100);

    ChangePageToBusPage(selectedBusStopInListView.BusStop, selectedTrack);

    _isWorking = false;
}

I don't have a Windows Phone so I can't really test the code but hopefully it will give you an idea. Good luck!

like image 193
Justin XL Avatar answered Oct 20 '22 11:10

Justin XL