I have the following problem: I have a Listview where each item is a custom control ("DisruptionIcon") that displays an icon, depending on the properties set for the custom control. An icon can have one shape out of many (here in the example it is simply βNoβ and βSquareβ). The problem is that if I scroll down in Listview and return after that, the icons are wrong. This leads to the following:
Before scrolling down:

After scrolling down and up:

Resources:
MainPage.xaml:
<Page x:Class="App1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Name="MainPg" > <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <ListView Width="200" ItemsSource="{Binding LineList, ElementName=MainPg}" > <ListView.ItemTemplate> <DataTemplate> <Grid> <local:DisruptionIcon DisplayName="{Binding DisplayName}" IconType="{Binding DisplayStyle}" Color1="{Binding Color1}" Color2="{Binding Color2}" /> <TextBlock Text="{Binding DisplayName}" Foreground="Red"/> </Grid> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid>
MainPage.xaml.cs:
public sealed partial class MainPage : Page { public MainPage() { LineList = new ObservableCollection<ServerLineDefinition>(); for (byte i = 0; i <= 250; i++) { var ds = new ServerLineDefinition("ID " + i, "FFFFFF", "000000", 1, i); LineList.Add(ds); } InitializeComponent(); } public ObservableCollection<ServerLineDefinition> LineList { get; set; } }
My user control: DisruptionIcon.xaml:
<UserControl x:Class="App1.DisruptionIcon" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Name="mainUc" mc:Ignorable="d" d:DesignHeight="34" d:DesignWidth="80" Width="80" Height="34" > <Grid> <local:DisplayIconTemplateSelector Content="{Binding IconType, ElementName=mainUc}"> <local:DisplayIconTemplateSelector.StyleNone> <DataTemplate> <Grid/> </DataTemplate> </local:DisplayIconTemplateSelector.StyleNone> <local:DisplayIconTemplateSelector.StyleSquare> <DataTemplate> <Rectangle Width="80" Height="32" Fill="{Binding Color2, ElementName=mainUc}" VerticalAlignment="Top" HorizontalAlignment="Left" StrokeThickness="2" Stroke="{Binding Color1, ElementName=mainUc}" /> </DataTemplate> </local:DisplayIconTemplateSelector.StyleSquare> </local:DisplayIconTemplateSelector> <Viewbox Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="8,0" > <TextBlock Text="{Binding DisplayName, ElementName=mainUc}" Foreground="{Binding Color1, ElementName=mainUc}" Height="auto" VerticalAlignment="Top" TextWrapping="NoWrap" FontWeight="Bold" TextAlignment="Center" Margin="0,-2,0,0" /> </Viewbox> </Grid>
This is the code for DisruptionIcon in disruptionicon.xaml.cs , where basically the properties are simply bound by DependencyProperties and the Colors will be converted to SolidColorBrush if they are presented as a string. This is what I need because of the design of the application:
public sealed partial class DisruptionIcon { public DisruptionIcon() { Color1 = new SolidColorBrush(Colors.White); Color2 = new SolidColorBrush(Colors.Black); IconType = DisplayStyle.None; DisplayName = ""; InitializeComponent(); } #region Color1
My TemplateSelector DisplayIconTemplateSelector.cs:
public class DisplayIconTemplateSelector : ContentControl { protected override void OnContentChanged(object oldContent, object newContent) { base.OnContentChanged(oldContent, newContent); ContentTemplate = SelectTemplate(newContent, this); } public DataTemplate StyleNone { get; set; } public DataTemplate StyleSquare { get; set; } public DataTemplate SelectTemplate(object item, DependencyObject container) { var quoteItem = (DisplayStyle)item; switch (quoteItem) { default: return StyleNone; case DisplayStyle.Square: return StyleSquare; } } }
And finally, my ServerLineDefinition-Class:
public class ServerLineDefinition : INotifyPropertyChanged { public ServerLineDefinition() { } public ServerLineDefinition( string displayName, string backgroundColor, string foregroundColor, int displayStyle, int id) { DisplayName = displayName; Color2 = backgroundColor; Color1 = foregroundColor; DisplayStyle = displayStyle; Id = id; } public int Id { get; set; } public string DisplayName { get; set; } public int DisplayStyle { get; set; }
It seems to me that there is a problem with Listview caching. If I replaced Listview with ItemsControl , which was damaged in ScrollViewer , the problem does not exist, but it uses much more memory and takes more time to load. In addition, if you uncomment the TextBlock , which is added as a comment in MainPage.xaml , you see in each line the correct identifier, but the wrong image, as shown in the screenshots.
Edit : If I put any control in a ScrollViewer , then it works slowly, but it works. It also works if I put the entire Code of DisruptionIcon.xaml directly into the MainPage location referenced by DirutpionIcon.