I have a WPF application running on a Windows 8.1 tablet using touch. After a whole lot of reading about how to solve some common touch specific problems I found this tutorial that really pointed me in the right direction.
My problem is that after implementing the tutorial my ScrollViewer stopped working unless I scroll directly from the scroll bar itself.
this is how my ScrollViewer (which is the top element in my window) looks like:
<ScrollViewer CanContentScroll="True" PanningMode="Both">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock HorizontalAlignment="Center"
FontSize="48"
Text="{Binding SelectedView.ViewHeader}"
TextAlignment="Center"
TextWrapping="Wrap" />
<Separator Margin="0,25" />
</StackPanel>
<ContentPresenter Grid.Row="1"
Margin="10,0,0,30"
Content="{Binding SelectedView}" />
</Grid>
</ScrollViewer>
Any suggestions on how to fix it?
EDIT:
The reason I chose the method above over the one suggested above is because it eliminated many controls focus problems I was having such as textboxes the need 2 or 3 touches to receive focus or comboboxes that stay open after selecting an item:
When using this method DisableWPFTabletSupport. You are disabling all tablet support which include ScrollViewer Touch screen. See my post in this link to achieve similar behavior (show/hide windows keyboard) without disabling tablet support.
Show & hiding the Windows 8 on screen keyboard from WPF
Related
For reference, this is a chat application. This should give you some idea of a final goal.
Additionally, I am very new to WPF. This is one of my first applications and I am making this as a proof of concept. I've been using Windows Forms up until this point, so any comparison or reference to it would help me understand a bit better.
So, the issue at hand:
The chat box for my chat application is a StackPanel (should it be?) which is programmatically populated with TextBlock elements. I need to find a way to scroll down this StackPanel once the available space runs out. I also need it to automatically scroll to the bottom (like a chat would; you wouldn't be able to see the most recent message otherwise).
The question: How can I make a ScrollViewer properly size dynamically with a StackPanel?
Additionally, I also need this StackPanel to size dynamically as the window is sized. This, in turn, would affect the scroll bar.
My current "solution" is to use a ScrollViewer with the StackPanel nested. However, the ScrollViewer and StackPanel do not size properly with a change in window size, as shown in screenshot #2. The XAML code and a screenshot of the designer is shown below.
<Window x:Name="Main" x:Class="dprCxUiDemoWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:dprCxUiDemoWpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Background="#FF171717">
<TextBox x:Name="ChatBox" TextWrapping="Wrap" Background="#FF4F4F4F" Foreground="White" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" RenderTransformOrigin="-0.118,12.093" Margin="146,0,0,1" VerticalAlignment="Bottom" Height="46" BorderBrush="#FFFF00F3" KeyDown="ChatBox_KeyDown"/>
<Image x:Name="DprLogo" Source="/dprCxUiDemoWpf;component/Images/logo1.png" HorizontalAlignment="Left" Height="60" Margin="10,0,0,10" VerticalAlignment="Bottom" Width="123"/>
<ScrollViewer Background="Red" Height="Auto" Width="Auto" ScrollViewer.CanContentScroll="True" Margin="146,0,0,0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" VerticalAlignment="Top" MinHeight="372">
<StackPanel x:Name="ChatPanel" Height="Auto" Width="Auto" Background="DimGray" ScrollViewer.CanContentScroll="True" />
</ScrollViewer>
</Grid>
</Window>
(source: gcurtiss.dev)
Please note the following regarding the first screenshot:
A. The black column (containing the logo) is simply the background color of the window; there is nothing there.
B. The gray portion is ChatBox (the StackPanel)
C. The pink highlighted box below is the text box where messages are entered.
I appreciate and accept any and all help!
You have to use the Grid panel properly. You layout its children by defining rows and columns. Grid is a column/row based layout container. Then configure row and column definitions to control the resize behavior of the cells and their content.
Using absolute positioning and sizes will of course prevent controls from responding to their parent's size changes. Most control stretch to fit the available space. But this requires dimension properties being set to Auto.
You said you are "more of a hands-on learner", but you should still read some documentations. Otherwise you will significantly slow down your progress until stagnation.
There are tons of blogs waiting for you to read them. To poke around in the dark will get you nowhere. You need at least to know the basics. Instead of waiting 13+ hours for a copy & paste ready answer, you could have finished multiple tutorials already and solve this on your own. Success is a good feeling. This is a very trivial problem.
Find yourself a good tutorial that you find easy to understand and start to experiment with the Grid after reading it.
According to your posted code, you obviously have zero idea how this panel works and how you can use it to align your controls.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<StackPanel />
</ScrollViewer>
<Image Grid.Row="1" Grid.Column="0"
Height="60"
Width="123 />
<TextBox Grid.Row="1" Grid.Column="1" />
</Grid>
I need to find a way to scroll down this StackPanel once the available space runs out. I also need it to automatically scroll to the bottom (like a chat would; you wouldn't be able to see the most recent message otherwise)
You should read about data-binding and MVVM first. Usually you hold an ObservableCollection of items on your VM and bind them to eg a ListBox on your View.
Then you can scroll-down the ListBox, each time a new item got added to your collection:
private void ScrollRecordsListToBottom()
{
if (RecordsList.Items.Count == 0)
return;
var lastItem = RecordsList.Items[RecordsList.Items.Count - 1];
RecordsList.ScrollIntoView(lastItem);
}
I'm working on a C# XAML app for windows 8.1/10 and I'm having trouble creating a scrollviewer that behaves how I want.
Pretty much I want the top scroller on the default page in the Windows Store app on Windows10. It looks like this when the screen is small:
Store Scroller
It scrolls sideways through items, snaps between them, and is operated not by a scrollbar but by scrolling buttons on the side. It also has page markers at the bottom and loops through content. Ideally in mine it would also be operable with the scrollwheel on your mouse.
What I want in my UI is this:
Icon Scroller
The purpose of this control is to cycle through available options for an icon, showing exactly three at any given time; the images are selectable. I have 9 icons total so I need 3 "pages" in this scrollviewer. I've somewhat accomplished this by using a scrollpanel with a stackpanel inside which itself contains three other stackpanels for my "pages". The scrollviewer is set to snap between items and it works great. Sample code of what I've created is the following:
<ScrollViewer x:Name="scroller" HorizontalScrollBarVisibility="Hidden" VerticalScrollMode="Disabled" VerticalScrollBarVisibility="Disabled" HorizontalSnapPointsType="Mandatory" Width="120">
<StackPanel x:Name="stack_Master" Orientation="Horizontal" Height="40">
<StackPanel x:Name="stack_Page1" Orientation="Horizontal">
<Image x:Name="image_Page1_Icon1" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page1_Icon2" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page1_Icon3" Style="..." Source="..." Width="40"/>
</StackPanel>
<StackPanel x:Name="stack_Page2" Orientation="Horizontal">
<Image x:Name="image_Page2_Icon1" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page2_Icon2" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page2_Icon3" Style="..." Source="..." Width="40"/>
</StackPanel>
<StackPanel x:Name="stack_Page3" Orientation="Horizontal">
<Image x:Name="image_Page3_Icon1" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page3_Icon2" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page3_Icon3" Style="..." Source="..." Width="40"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
The pages scroll nicely with animations when using the mouse wheel. The page indicator should be easy enough to implement using some C#. My plan for the looping was to have "decoy" versions of Page3 and Page1 at the start and end of stack_Master respectively. Then once the animation finishes to programmatically change to the actual page with no animation. This would imitate a circular scroller.
The problem I'm running into is how can I implement the scrolling buttons? I don't see any methods for scrollviewers on MSDN which will change the position of the scrollviewer while maintaining the smooth animation, instead only ones that instantly change the position abruptly. If such a method existed then I could tie that to some buttons on the side of the scrollviewer.
If this method doesn't exist than I also saw a solution for when snapping isn't enabled. Essentially the button would move the scroller say 10 pixels every 50ms, simulating a flowing movement. I don't think that would be possible when snapping between pages.
It would be simple if there was a style for the scrollviewer to simply have the arrow buttons from the default scrollbar, without the actual bar between them. Does this exist?
Any help is appreciated.
I'm trying to do news app for windows store with c# and xaml..
In this project, I created a Panorama GridView like windows phone 8.. And inside of this Panorama GridView, I created small gridviews for cathegories..
Structure is like this in Document Online;
-<Grid> (whole page)
-<Grid> (Header/Logo etc.)
-<PanoramaGridView> (All cath will be under of this)
-<HotNewsGridView>
-<HotNewsGrid>
-<GroupHeaderTextBlock>
-<HotGridView>
-<SportNewsGridView>
-<PoliticsGridView>
-<GalleryGridView>
And first side of code..
<GridView x:Name="PanoramaGridView"
Grid.Row="1"
Style="{StaticResource GridViewStyle1}"
ItemContainerStyle="{StaticResource GridViewItemStyle2}">
<GridViewItem Margin="0,0,2,0" VerticalAlignment="Top">
<Grid Margin="30,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition/>
</Grid.RowDefinitions>
<GridView x:Name="HotNewsGrid"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource MansetItemTemplate}"
Grid.Row="1"
SelectionChanged="HotNewsGrid_SelectionChanged"/>
<TextBlock x:Name="GroupHeaderTextBlock"
HorizontalAlignment="Left"
Margin="0,0,-7,-18"
Grid.RowSpan="1"
TextWrapping="Wrap"
Text="Hot News"
Foreground="DarkGreen"
VerticalAlignment="Top"
Style="{StaticResource SubheaderTextStyle}"/>
</Grid>
The problem is, I cannot scroll when my mouse cursor come on the "HotNewsGrid" grid. I can only scroll from top and bottom of the application..
I think, my PanoramaGridView is okay with scrolling but when my cursor comes subgridviews (like hot news gridview) it stops scrolling, cannot scroll from it. I tried to put IsSwipeEnable, ScrollViewer.HorizontalScrollMode="Enabled" etc.. Did not worked..
I do not want scrolling the "HotNewsGrid". I just want to continue scrolling when my cursor comes on it..
I hope you understand me.. This is a very big problem for me..
Waiting your helps..
Thank you..
Add this Template to your GridView
<GridView.Template>
<ControlTemplate>
<ItemsPresenter />
</ControlTemplate>
</GridView.Template>
and you will be able to scroll using a mouse.
Note that a side effect of this is that you can no longer swipe select on your GridView
I'm currently devloping an App for WP8 and am having a Problem when navigating Panorama or Pivot-Views.
For example:
I have a Panorama which itself contains a few Buttons on every Page. If I try to navigate between those Pages, I sometimes accidentally manage to Raise a Click-Event for some Buttons.
After trying to reproduce the bug, I found out, that this mainly happens when I swipe over a short distance. If I swipe long distance, the bug doesn't appear and no event is raised.
I am using Command Binding for Eventhandling, should I maybe change this? I'm really trying to figure this out, but I still can't find a way other than a Service which disables all Events if a swipe occurs.
Thanks in advance for any Help you can give me!
PS: Here is some code, don't know if/how it might help:
<phone:Panorama x:Name="Panorama" Title="{Binding LocalizationService.Resources.ApplicationTitle}">
<phone:PanoramaItem Header="{Binding LocalizationService.Resources.MainPage_Header}" HeaderTemplate="{StaticResource PanoramaItemHeaderTemplate}">
...
<Button Command="{Binding CmdNavigateToZipSearch}" Style="{StaticResource PizzaButtonAccentStyle}" Width="214" Height="172">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="/Assets/icon_plz-suche.png" Stretch="Uniform" Height="77" Margin="1,6,0,0" />
<TextBlock Grid.Row="1" Text="{Binding LocalizationService.Resources.MainPage_ZipSearch_Label}" Style="{StaticResource PizzaTextContrastStyle}" />
</Grid>
</Button>
...
Internally (AFAIK) the command on a button is fired based on a click event. Instead of using the click/command event use an EventToCommand solution to bind your command to the Tap event as this cannot be fired at the same time as a swipe due to it's threshold of movement.
I am writing a Windows Phone 8 app, and I am having some problems with the UI. I want a control that will stretch to the width of the whole screen, and will flow its children controls horizontally (to fill the space).
Currently, I have a a StackPanel with Orientation = Horizontal, but it doesn't allow the children control (a slider) to have a HorizontalAlignment=Stretch (that actually stretches). I can manually strech the slider, but I don't want to have hardcoded sizes..
Here is the code:
<StackPanel Orientation="Horizontal">
<TextBlock Text="Hue Bins" />
<Slider x:Name="HueBins" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Value="24" Maximum="36" Minimum="1"/>
</StackPanel>
and the resulting image:
In normal WPF, there is the Dockpanel control, but that doesn't seem to exist for WP8. Is there anyway to emulate that behavior?
You can use Grid with two columns:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Hue Bins" />
<Slider x:Name="HueBins" Grid.Column="1" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Value="24" Maximum="36" Minimum="1"/>
</Grid>
You could try the version extracted from Silverlight Toolkit here, with some adjustments they did for WP7
http://www.geekchamp.com/articles/using-dockpanel-in-wp7
or use the whole Silverlight Toolkit if you need more stuff from it
http://silverlight.codeplex.com/
(since Windows Phone Toolkit that was derived from it doesn't seem to contain DockPanel)
some info (but broken download link) on what is needed to compile DockPanel are at http://matthiasshapiro.com/2010/06/28/using-wrappanel-and-dockpanel-in-windows-phone-7-with-blend/
Update: I used the info I mentioned above to set up http://DockPanel.codeplex.com. It works fine, apart from the case where all the top/left/right/bottom/middle items are all added together in the layout, at least on Windows Phone it does some wrong layout in that case