WPF goes to the top of each pages when navigating/reloading page - c#

I'm very new to WPF .net 5.0 framework. Every time I navigate to a different page in a frame, it maintains the scroll position instead of going back to the top of the page. May I know if there is a way to make sure that it goes to the top of the page every time I navigate? Thank you!
this is the xaml
<ScrollViewer Height="1000" Width="1000" HorizontalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="23*"/>
<RowDefinition Height="477*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock HorizontalAlignment="Left" Margin="10,0,0,0" TextWrapping="Wrap" VerticalAlignment="Center" FontWeight="Bold" Foreground="#FF5B5858"><Run Language="en-sg" Text="ADD NEW APPLICATION"/></TextBlock>
</Grid>
<Grid Grid.Row="1" Margin="0,10,0,0">
<Border CornerRadius="0,0,30,0" BorderThickness="1">
<Frame x:Name="wizardFrame" Content="Frame" HorizontalAlignment="Center" Width="1002" Margin="0,9,0,471" NavigationUIVisibility="Hidden"/>
</Border>
</Grid>
</Grid>
</ScrollViewer>
This is the code behind
wizardFrame.NavigationService.Navigate(new LocationPage1());
This is what i use to navigate to different pages in a frame
this.NavigationService.Navigate(new GenerateApplicationNumberPage2());

Your issue is that the ScrollViewer has no relation to the Frame, so it won't react to the Frame navigating.
In order to fix that, I see two solutions (pick one):
You name your ScrollViewer (e.g: mainScroll), and in the code-behind, you subscribe to the Navigated event of your Frame, so as to call ScrollViewer.ScrollToTop(), as suggested in a comment.
// Somewhere in the constructor after InitializeComponent();
wizardFrame.Navigated += (_, __) => mainScroll.ScrollToTop();
You remove the ScrollViewer from your main page, and add one as the root element in the XAML of each Page (LocationPage1, GenerateApplicationNumberPage2, and any other page). It will work because you create a new page each time you navigate (which isn't very good for resource management, but this is not the subject here).
The difference will be that the TextBlock with "ADD NEW APPLICATION" will always be visible above the Pages instead of being inside the ScrollViewer.
<Page x:Class="Namespace.LocationPage1">
<ScrollViewer Height="1000" Width="1000">
<!-- Your page content here -->
</ScrollViewer>
</Page>

Related

Override MediaElement on top of Webview2

I created a WPF project in which I need display two StackPanels like this:
This screen is child of main Grid
StackPanel 1 will be displayed without any alternation of width and height and I need to display the entire second StackPanel on top of previous StackPanel. Using Canvas and DockPanel doesn't help me in this case.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Center" Grid.Row="0" x:Name="web1">
<wv2:WebView2 Name="MyWebView"
Height="800" >
</wv2:WebView2>
</StackPanel>
<StackPanel Grid.Row="0" x:Name="videoPlayerPanel">
<Canvas >
<local:VideoPlayer x:Name="videoPlayer" Background="AntiqueWhite"/>
</Canvas>
</StackPanel>
</Grid>
I agree with #thatguy answer , if we use the zIndex we can overlap the element in WPF, But the question here is related to webview2 and mediaElement.
As of now webview2 not allow another element to come on top.
So there is no way to display your mediaElement on top of webview as of now.
Reffer to this Link for this issue : Webview2 issue
You can try to display mediaElement using popup but this will give other problems
I think this is the only answer to your question right now .
The order in which you define the StackPanels inside the Grid matters. The next item is displayed above the previous one. In your example, videoPlayerPanel will be above web1, because it is defined after web1. There are two options to alter this behavior.
Change the order, define videoPlayerPanel before web1, to display web1 above videoPlayerPanel.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" x:Name="videoPlayerPanel">
<Canvas >
<local:VideoPlayer x:Name="videoPlayer" Background="AntiqueWhite"/>
</Canvas>
</StackPanel>
<StackPanel VerticalAlignment="Center" Grid.Row="0" x:Name="web1">
<wv2:WebView2 Name="MyWebView"
Height="800" >
</wv2:WebView2>
</StackPanel>
</Grid>
Define the Z-Order explicitly by setting a ZIndex for the items.
Gets or sets a value that represents the order on the z-plane in which an element appears. [...] The greater the value of a given element, the more likely the element is to appear in the foreground.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Center" Grid.Row="0" x:Name="web1" ZIndex="1">
<wv2:WebView2 Name="MyWebView"
Height="800" >
</wv2:WebView2>
</StackPanel>
<StackPanel Grid.Row="0" x:Name="videoPlayerPanel">
<Canvas >
<local:VideoPlayer x:Name="videoPlayer" Background="AntiqueWhite"/>
</Canvas>
</StackPanel>
</Grid>
The default ZIndex is zero, and that explains why the order in the Grid matters.
Members of a Children collection that have equal ZIndex values are rendered in the order in which they appear in the visual tree. You can determine the index position of a child by iterating the members of the Children collection.

C# Windows IoT core - Auto Scroll text in Textblock from left to right continuously

I am working on a Digital Signage project using Windows IoT core. So far I managed to design the grid and scroll images and videos. Now I have added a text block at the bottom of the grid and text in it should continuously scroll from left to right
For more detail example I need a MARQUEE of text in the bottom side.
Main page XAML code:
<Page
x:Class="Digital_Notiec_Board_V1._2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Digital_Notiec_Board_V1._2"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="#FF222222" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="1800"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
</Grid.RowDefinitions>
<Image x:Name="imageInstance" Visibility="Collapsed" Grid.Row="0"/>
<MediaElement x:Name="audioInstance" Visibility="Collapsed" Grid.Row="0"/>
<MediaElement x:Name="videoInstance" Visibility="Collapsed" Grid.Row="0"/>
<ScrollViewer Grid.Row="1" Background="#FF5A80FF">
<TextBlock x:Name="ScrollText" TextWrapping="Wrap" Foreground="White" Text="AJ Y" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollMode="Auto" SelectionHighlightColor="#FF2D5DFF">
</TextBlock>
</ScrollViewer>
</Grid>
Well if you need to show a Marquee text only then I would advise you to use a custom control that allows you to put a text as a marquee.
Luckily, there is a GitHub repo for the same. You can check it out on `GitHub at MarqueeTextControl
works perfectly fine, I just tried it. If you need any further help, please use the comments section.

Prevent a StackPanel inside a ScrollViewer to move the selected item automatically to the top

I have a structure in WPF as follows:
<Grid x:Name="Grid" Background="#FFE5E5E5">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Height="790" Margin="13,9,10,0" CanContentScroll="True" HorizontalContentAlignment="Center" VerticalContentAlignment="Stretch">
<StackPanel x:Name="StackPanel" Height="770" Width="650" HorizontalAlignment="Center"/>
</ScrollViewer>
</Grid>
My program puts several UserControls inside the StackPanel. When I select one of the elements of the UserControl that is not on the top of the ScrollViewer, it automatically moves to the top.
Is there a way to prevent this and leave it in place and only allow the user to scroll up and down whenever he/she wants to?

How to prevent the Content of a UserControl from being overridden?

I'm new to Windows 10 app development. I'm trying to embed my custom UserControl in a page in my application. For some reason, the content is being completely replaced by whatever I put inside it in the XAML page. To give a better explanation, here is the code:
AppView.xaml (the control)
<UserControl
x:Class="Sirloin.AppView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Sirloin"
xmlns:h="using:Sirloin.Helpers">
<SplitView x:Name="splitView" DisplayMode="CompactOverlay">
<SplitView.Pane>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--The hamburger-->
<Button Click="OnHamburgerClicked" Grid.Row="0" Style="{StaticResource MenuButtonStyle}">
<Button.DataContext>
<local:MenuItem Symbol=""/>
</Button.DataContext>
</Button>
<!--Buttons just below the hamburger-->
<ListView x:Name="topView"
Grid.Row="1"
ItemTemplate="{StaticResource ListViewItemTemplate}"/>
<!--Buttons toward the bottom of the menu-->
<ListView x:Name="bottomView"
Grid.Row="3"
ItemTemplate="{StaticResource ListViewItemTemplate}"/>
</Grid>
</SplitView.Pane>
<SplitView.Content>
<!--Where I'd like the content specified in MainPage to appear-->
<Frame x:Name="frame" Background="White"/>
</SplitView.Content>
</SplitView>
</UserControl>
MainPage.xaml
<Page
x:Class="Sirloin.Example.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="using:Sirloin"
xmlns:local="using:Sirloin.Example">
<s:AppView>
<Grid Background="White">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="Hello, world!"/>
</Grid>
</s:AppView>
</Page>
When MainPage renders in the VS designer, it's as if the contents of my user control have been completely gutted out and replaced with whatever is specified in the main page. To give you an idea, here is a screenshot of the designer:
As you can see, there is no menu or SplitView or whatever I've put in my custom control; the only thing that's present is the TextBlock I've specified in the XAML for MainPage.
Anyway, why does this happen and what can I do to fix it?
EDIT: Found the solution I was looking for here, but Peter Duniho's answer has been accepted as it provides a better explanation of what's going on.
UserControl is a subclass of Control (which is similar to WPF's ContentControl). It can have only one child. So you are explicitly overriding the content yourself. By specifying a child element for your AppView in the Page XAML, you are setting the content of the control. This takes precedence over whatever content was specified in the UserControl's own XAML.
Unfortunately, it's not very clear what it is you expected to happen. Maybe you want to provide a property for additional content, which the AppView class can use to add to its own content. Or maybe you should be allowing the client code to provide a DataTemplate and some kind of data item object (e.g. model class), which is used in a ContentPresenter or similar in the AppView XAML.
But whatever you're trying to do, you'll have to do it without using, and overriding the current value of, the implicit Content property of the UserControl in the Page XAML.

WPF controls do not align

NOTE: This is one of the first time I'm using WPF.
I am trying to align a certain control, let's say a button for now, in the bottom right corner. But when I debug my application, it misses 8 pixels to the bottom and right. I will attach 2 pictures to show you what happens.
How do I keep the button in place?
My XAML code:
<Window x:Class="Plugin_Manager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Plugin Manager" Height="350" Width="525" Loaded="Window_Loaded_1">
<Grid x:Name="GridMain">
<Button Content="Refresh" Margin="432,288,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="75"/>
<ListView HorizontalAlignment="Left" Height="273" Margin="10,10,0,0" VerticalAlignment="Top" Width="497">
<ListView.View>
<GridView>
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
</Grid>
If you choose to use Grid layout you should try to avoid placing objects via Margin. Margin should be used to create buffer around an object, not move it to a specific point in the window. Use the layout manager's power to your advantage!
Here is a Grid example that does what you are looking for.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Grid.Row="0" />
<Button Grid.Row="1" HorizontalAlignment="Right" Content="Push Me" />
</Grid>
I would also read up on Layout Manager in WPF. There are several; each having its own advantages & disadvantages.
Here is a DockPanel version.
<DockPanel>
<Button DockPanel.Dock="Bottom" HorizontalAlignment="Right" Content="Push Me" />
<ListView />
</DockPanel>
To create your buffer between the button and the window chrome you could do a few different things:
<Grid Margin="10"> will apply a 10 pixel space between all content and the window chrome on all side.
<Grid Margin="0,0,10,10"> would indent all content, but only on the right & bottom.
<Grid Margin="10,0,10,10"> indents all around, except the top (I commonly do this one, with a different margin value).
<Button Margin="0,0,10,10"> would indent only the button from the chrome (this is the direct answer to your comment question).
Replace the Grid above with DockPanel for the second example, or whatever other Layout Manager you are using.
A usability side note: Your confirmation buttons (I'm assuming your button will be an Ok/Cancel type button) should not be indented differently from the rest of your content. All controls that butt up against the right margin should do so at the same point (i.e., you can draw a vertical line down the right side of them all).
So, using your question's example: your button should not be indented 10 pixels to the right while your list box is not. Keeping things lined up will improve the overall look to your application.
(this ends my "usability and look-and-feel is important" side note) :)
<Button VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5"/>
Some code example will help. Try using the alignment in xaml for your button as shown below. Ensure that the margins on the button are 0.
<Button Margin="0" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
Looking at the sample code, it is your margins and the alignment you have that are probably causing that.
Just some pointers that may help. Instead of using large margins to align the controls, I find it much easier to work with Column and Row definitions on the grid. This way you can align your controls using the grid and they will size properly as you resize your window. I attached an example in hopes it helps in your new adventures with WPF!
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Version Date" Margin="3" VerticalAlignment="Center"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding DateSubmitted}" Margin="3"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="Report" Margin="3" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding ReportName}" Margin="3"/>
</Grid>

Categories

Resources