Image flickers in ListView datatemplate - xaml

could someone tell me, how can I avoid image flickering in Datatemplate? Everytime I change the source through binding (MVVM pattern), the image in ListViewItem flickers. For other images in app I've used ImageOpened event in code-behind. But I can't be used when I have DataTemplate.
EDIT:
DataTemplate:
<DataTemplate x:Key="ContactItemDataTemplate" x:DataType="contactData:Contact">
<Grid MinHeight="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" x:Name="MainImage" Source="{x:Bind ImageStatusUri, Mode=OneWay}" Margin="0,8,12,8">
</Image>
<TextBlock Grid.Column="1" Text="{x:Bind Nickname, Mode=OneWay}" Foreground="Black" TextAlignment="Center"
VerticalAlignment="Center" FontSize="15" HorizontalAlignment="Left"/>
</Grid>
<Rectangle Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" StrokeThickness="0.4" Height="0.4"
VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Stroke="#D1D3D4"/>
</Grid>
</DataTemplate>
type Contact implements INotifyPropertyChanged.
EDIT2:
WriteableBitmap is working, but I have 3 images with scaling factors 100, 200 and 400. It always choose the image with scale 400. When I use normal binding no WriteableBitmap, it take image with scale 100.

The best solution here is for you to sub-class the Image control, overriding the Source property and controlling the transition from one image to another with a flicker-less flow. Learn here: https://mva.microsoft.com/en-US/training-courses/xaml-for-windows-10-controls-14482

Related

How to set scroll-viewer inside scroll-viewer in UWP

i want to display a scroll-viewer inside scroll-viewer. The parent scroll-viewer should work vertically and child scroll-viewer work both horizontal and vertical.
i tried to add whole grid inside the parent scroll-viewer when i am resize the page the parent scroll-viewer is not working and child scroll-viewer is horizontal work not vertical.
<Grid>
<VisualStateManager> ...
<ScrollViewer >
<Grid HorizontalAlignment="Stretch" Height="1000" Margin="0,0,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="COne" Width="59"/>
<ColumnDefinition x:Name="CTwo" Width="31*"/>
<ColumnDefinition x:Name="CThree" Width="44*"/>
<ColumnDefinition x:Name="CFour" Width="53*"/>
<ColumnDefinition x:Name="CFive" Width="116*"/>
<ColumnDefinition x:Name="CSix" Width="40*"/>
<ColumnDefinition x:Name="CSeven" Width="262*"/>
<ColumnDefinition x:Name="CEight" Width="234*"/>
<ColumnDefinition x:Name="Cnine" Width="350*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="ROne" Height="45*"/>
<RowDefinition x:Name="RTwo" Height="23*"/>
<RowDefinition x:Name="RThree" Height="432*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border CornerRadius="5" extensions:Mouse.Cursor="Hand" BorderBrush="#E1E1E1" BorderThickness="1" Grid.ColumnSpan="8" Margin="7,18,31,395" Grid.Column="1" Grid.Row="2" >
<ScrollViewer x:Name="Gridscroller" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Grid.ColumnSpan="8" Grid.Column="1" Grid.Row="2" >
<Toolkit:DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible" extensions:Mouse.Cursor="Hand" Style="{StaticResource GridBackground}" BorderBrush="Transparent" BorderThickness="5" AllowFocusOnInteraction="False" x:Name="UserListView" SelectionMode="Single" FontSize="16" RelativePanel.AlignLeftWithPanel="True" Grid.ColumnSpan="8" Grid.Column="1" Grid.Row="2" OrderChanged="UserListView_OrderChanged" Tapped="UserListView_Tapped" >
.
.
.
</Toolkit:DataGrid>
</ScrollViewer>
</Border>
<TextBlock FontFamily="{StaticResource inventorySemiBoldFont}" Foreground="#444444" FontSize="13" Visibility="Visible" x:Name="SearchMessage" Grid.Column="3" HorizontalAlignment="Left" Margin="0,74,0,0" Grid.Row="2" VerticalAlignment="Top" Grid.ColumnSpan="4" Width="391"/>
<StackPanel HorizontalAlignment="Center" Margin="0,486,32,0" Grid.Row="2" VerticalAlignment="Top" Grid.ColumnSpan="7" Grid.Column="2" />
</Grid>
</ScrollViewer>
</Grid>
In ScrollViewer, scrolling only when the content width/height is larger than the container width/height, but the internal viewable area of the ScrollViewer is infinite, so if you want the child ScrollViewer to work, you need to set the width/height for it.
like:
<ScrollViewer>
<ScrollViewer width="500" HorizontalScrollBarVisibility="Auto" HorizontalScrollMode="Auto">
<!-- Content here -->
</ScrollViewer/>
</ScrollViewer>
Best regards.

ListView gets not scrollable

I have a proble which seems pretty common and has been asked alot, but I can't find a fixing solution for my problem.
So I try to use 3 listviews in in one page all shall have a title and an explaining image, but instead of designing all 3 ListViews in one page I outsourced one listview with image and title into a control, which I use in my page.
The 3 Controls are placed in a grid. When the listview items get filled thy scrollbar should become visible if the remaining space is no longer enough but it won't show.
I provided a sandbox project where I placed the control and etc. like in the application I'm working on. SampleProject
Their you just need to press start and the listviews get filled. But they don't show the scrollbar.
Thanks in advance!
Edit 1:
As requested I share my code below. If you open up the sample project then you do not need to read further until a second edit is done.
Control containing listview:
<Grid>
<Grid x:Name="Section"
HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="grdTitleArea"
HorizontalAlignment="Stretch"
Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<BitmapIcon
VerticalAlignment="Center"
HorizontalAlignment="Center"
Tapped="grdTitleArea_Tapped"
UriSource="ms-appx:///Assets/area.png"
Height="40" />
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Tapped="grdTitleArea_Tapped"
Text="Area"
Grid.Column="1" />
</Grid>
<!--<ScrollViewer
VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
VerticalScrollMode="Enabled"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
HorizontalScrollBarVisibility="Hidden"
HorizontalScrollMode="Disabled"
>-->
<ListView x:Name="ListView"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Auto"
Grid.Row="1">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="1"
Margin="1"
Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding ActionDescription}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--</ScrollViewer>-->
</Grid>
</Grid>
Control which contains the control above 3 times:
<Grid x:Name="ProgressControl">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:SynchronizeSettingsControl
Visibility="Visible"
x:Name="Settings" />
<local:SynchronizeSectionControl
x:Name="ActualAction"
Visibility="Visible"
Grid.Row="1" />
<local:SynchronizeSectionControl
x:Name="Error"
Visibility="Visible"
Grid.Row="2" />
<local:SynchronizeSectionControl
x:Name="Log"
Visibility="Visible"
Grid.Row="3" />
</Grid>
Page which contains the control which contains the listview:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
Text="Demo"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Width="70"
VerticalAlignment="Stretch"
Content="Useless Button" />
</Grid>
<Controls:SynchronizeControl
x:Name="ctlSync"
Grid.Row="2"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
<Button VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
x:Name="btnStart"
Content="Start"
Tapped="btnStart_Tapped"
Grid.Row="3" />
</Grid>
The problem is you used Auto height in the page. This means basically that the page tells the local:SynchronizeSectionControl control: "You can use whichever height you want".
The control then has * as the height of the second row which means "use the rest space available". But because the page offered essentially "infinite height", the ListView height will stretch as much as possible to accommodate for all its items and hence it doesn't scroll, as its height is big enough to display everything, although it is cut off and not visible, because the window height is of course limited.
The thing is you used the Auto property for the height of your rows in your control.
This works fine is the control you use uses a definite space. Like a button or similar stuff. But when the control can extend indefinitely the allocation for the space gets screwed up.
Basically the control displays at its maximum size but extends way over its boundaries.
You can prevent that when you use the * as a Height value.
This will lead to the control taking up all the space available. You can further limit this with using the MaxHeight property.
If you do it that way it will display a scrollviewer when necessary and it will even resize when you change the window size.

UWP TextBox won't stretch in StackPanel

I have a TextBlock and TextBox controls inside StackPanel, and I need to stretch TextBox to resize by the parent size in UWP.
<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
<TextBlock Text="Name:" VerticalAlignment="Center" Width="130" />
<TextBox VerticalAlignment="Center" HorizontalAlignment="Stretch" />
</StackPanel>
This not works.. Any ideas?
The problem is the stack panel will only stretch to the size of the child elements so in your example you will only see one Textblock of 130 pixels and you will not see the TextBox.
To get the functionality you desire you should use a grid with two columns one 130 pixels and the other being * to fill up the entire column space that is available.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Name:" VerticalAlignment="Center" Width="130" />
<TextBox Grid.Row="0" Grid.Column="1"/>
</Grid>
I usually wrap a TextBlock and TextBox pair inside a DockPanel
<DockPanel Grid.Column="0" Grid.Row="1" >
<TextBlock Text="Name:"
VerticalAlignment="Center"
Margin="5"
/>
<TextBox VerticalAlignment="Center"/>
</DockPanel>
Edit
For UWP which doesn't have DockPanel:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="1" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="Name:"
VerticalAlignment="Center"
Margin="5"
/>
<TextBox Grid.Column="1"
VerticalAlignment="Center" HorizontalAlignment="Stretch" />
</Grid>
</Grid>
I worked out a similar problem in UWP
<StackPanel Margin="{StaticResource SmallTopBottomMargin}" Orientation="Vertical">
<TextBlock Text="Project Name:" />
<TextBox /> <--full width
<TextBlock Text="Exported Template:" /> <--full width
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBox /> <--max width - button width
<Button Grid.Column="1">...</Button>
</Grid>

XAML element inside of ItemsControl DataTemplate sometimes has null parent (WinRT)

I'm making a win8 app. I have an ItemsControl with a DataTemplate. Inside this DataTemplate, there is a Grid. Inside this Grid there is a WebView and a ProgressRing. I have an event for LoadCompleted on the WebView, at which time I want to disable the ProgressRing. My thought was to use the following:
ProgressRing pr = ((sender as FrameworkElement).Parent as Grid).Children.First(t => t.GetType().Equals(typeof(ProgressRing))) as ProgressRing;
pr.IsActive = false;
And this works sometimes, but sometimes it claims that ((sender as FrameworkElement).Parent) is null. I verified from debugging that in these cases, the sender is still the correct WebView. The WebView is being shown on the screen and is formatted correctly - so how could its parent be null?
Here's the XAML:
<ItemsControl Margin="40,0,40,0" x:Name="resultsItemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="50,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" MaxWidth="150"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="100" MaxWidth="100"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="viewInBrowser" IsEnabled="False" Style="{StaticResource PreviewLinkAppBarButtonStyle}" Margin="0,0,40,0" Click="viewInBrowser_Click_1"></Button>
<TextBlock HorizontalAlignment="Left" TextAlignment="Left" Grid.Column="1" FontSize="30" Margin="0,20,0,20" FontWeight="Bold" FontFamily="Georgia" VerticalAlignment="Center" Text="{Binding Name}"></TextBlock>
<ProgressRing x:Name="loadingProgressRing" Margin="20,0" Grid.Column="2" Foreground="White" IsActive="True" HorizontalAlignment="Left" VerticalAlignment="Center"></ProgressRing>
<WebView ScriptNotify="WebView_ScriptNotify_1" Grid.Column="0" Grid.ColumnSpan="14" Grid.Row="1" Source="{Binding CurrentSearchUrl}" Width="0" LoadCompleted="WebView_LoadCompleted_1"></WebView>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I wouldn't use a WebView in an ItemsControl at all, but you could try putting your entire template in a UserControlm then you handle the event inside of the UserControl and don't need to care about sender, since you can just name the Grid and access a named Grid.

Width of controls inside listbox not changing after orientation change

I have a grid inside stackpanel which is inside a listbox.
This grid has a few control elements like rectangles and textblocks.
They stretch to the entire width in portrait but not in landscape.
Snapshot of emulator
This is the XAML:
<ListBox Name="PassList" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch">
<Grid Name="StackPanelWidth" Width="{Binding ElementName=PassList, Path=ActualWidth}">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="{Binding ElementName=StackPanelWidth, Path=ActualWidth}"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="White"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
RadiusX="10"
RadiusY="10"
/>
<Rectangle Fill="White"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="0,10,0,0"
/>
<Rectangle Fill="DarkGray"
Grid.Row="0"
Grid.Column="1"
Height="1"
VerticalAlignment="Bottom"
/>
<TextBlock Name="Country"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Left"
Margin="10,0,0,0"
VerticalAlignment="Center"
Text="{Binding Country}"
Foreground="Black"
FontWeight="Bold"
/>
.............
.............
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Is there any thing wrong with my code?
Any help will be appreciated.
Thanks.
why are you doing this?
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="{Binding ElementName=StackPanelWidth, Path=ActualWidth}"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
Here you are somehow specifying the width because of which its not resizing.
Also the stackpanel will automatically adjust to its child width, so no need to specify binding if thats what you were trying to do.