I'm trying to resolve some layout problems in my Xamarin.Forms application. For example, when height of content is higher than body content height, then lists will collapse.
I have undefined amount of lists with custom item templates. I want to remain all height of each list and have possibility of scrolling them.
I tried use StackLayout but it doesn't support scrolling. When I use ScrollView, the Auto property doesn't work correctly (there is ambigous space between each of lists).
My code looks like this:
<Grid>
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"> //Header
...
</Grid>
<StackLayout Grid.Row="1"> //Group of lists
<ListView x:Name="firstList" ItemTemplate="..." ItemsSource="...">
</ListView>
<ListView x:Name="secondList" ItemTemplate="..." ItemsSource="...">
</ListView>
...
</StackLayout>
</Grid>
How can I position these lists on full height?
What you try to achieve is very ambiguous from the mobile app perspective. Think the other way around: While your screen is full of stacked ListViews, how would the system know it has to scroll down the page or scroll down the current ListView?
Also nesting ListView into ScrollView is a very bad practice because:
ListView implements its own scrolling.
ListView will not receive any gestures -> they will be handled by the parent ScrollView.
also ListView can have customized header and footer that scrolls with the elements of the list, potentially offering the functionality that the ScrollView was used for.
If you want to stick to this layout, your option here would be to design your own implementation of your control using custom renderers and manage the gesture.
Hope it helps and happy coding!
Related
I am trying to create a Main Window that will have a Header for navigation/buttons, and a footer for displaying information.
(similar to the top and bottom bars on StackOverflow.com)
What is the best way to make the Main Window function as a container that could display any page in between the header/footer?
I would create a 3 row Grid, with the center item being a ContentControl. Bind it to a CurrentPage property on your view model.
Create a Base Page class, and subclass it for each page of data you want to display. This subclass is also the viewmodel for each individual page.
Add a DataTemplate for each subclass of Page for the ContentControl to use, making sure to specify the Type attribute (This is what physically attaches the page type to the UI based on the CurrentPage property). The content of the DataTemplate should be a UserControl that contains the UI for each page type.
Now when you want to change pages, just set CurrentPage to an instance of the page you want, and it will automatically change.
This pattern will keep each page's UI separate from all the other, and gives them a strong view model (the Page subclass). It allows for super easy changing of pages. and follows the MVVM pattern nicely. You can even load all your pages in to a list that you present to the user. With a little more binding the user selecting a page can flow right in to the page change behavior with very little work.
create a page with 3 rows. The top row being a height of 'auto' the middle row being of height '*' and the bottom row being height 'auto' as well. The top and bottom row will take up as much room needed for the header and footer and the middle row will take up the rest of the room.
You can use a Grid
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<local:TopPage Grid.Column="0" Grid.Row="0" />
<local:MidPage Grid.Column="0" Grid.Row="1" />
<local:BottomPage Grid.Column="0" Grid.Row="2" />
</Grid>
I'm trying to change the behaviour when there's on-screen keyboard presence similar to what is described on https://msdn.microsoft.com/en-gb/windows/uwp/input-and-devices/respond-to-the-presence-of-the-touch-keyboard?f=255&MSPPError=-2147217396 but not actually clarified as to how to achieve:
In some cases, there are UI elements that should stay on the screen
the entire time. Design the UI so that the form controls are contained
in a panning region and the important UI elements are static.
This is my page's basic xaml layout:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="titlebar" Grid.Row="0" />
<RichEditBox x:Name="content" Grid.Row="1" />
</Grid>
What I want is for the titlebar element to still be visible on-screen when the touch-screen keyboard is opened. At the moment, what's happening is when the on-screen keyboard is called, the page is automatically scrolled down so that the RichEditBox appears at the very top of my view (requiring me to scroll up in order to get the titlebar back into view).
Any guidance on how to achieve the behaviour I'm after will be much appreciated.
Put both header TextBlock and RichTextBox in a Grid and then use translateY on the Grid's transform when RichTextBox receive focus.
Maybe something like this https://social.msdn.microsoft.com/Forums/windowsapps/en-US/99652e87-113c-47fa-a8e7-60f11fc9f160/virtual-keyboard-covering-textbox
http://blog.jerrynixon.com/2013/08/windows-8-xaml-manipulation-using.html?m=1
I have the problem, that my Grid is not filling the space as I want it.
Here some code:
<HubSection>
<Grid Width="850">
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="*"/>
<RowDefinition Height="310"/>
</Grid.RowDefinitions>
<Input:RadDatePicker Grid.Row="0" Value="{Binding CurrentDate, Mode=TwoWay}" />
<ListView
Grid.Row="1">...
</ListView>
<Grid Height="310"
Grid.Row="2">...
</Grid>
...
I want that the middle row is filling the space up of the hubsection. Instead it now just fills up when the listview contains enough items.
Any idea?
Now the filled ListView:
I would try setting the VerticalContentAlignment of the HubSection to Stretch as well as setting the VCA of the outer grid to that option. I'm suspecting the default might be Center or Top and so the minimizing vertical alignment control from the parent control and the expanding star-sized row setting of the inner grid come in a little bit of a conflict that some layout prioritizing rules probably resolve in getting the VCA rule to win.
For similar layout issues it is usually best to analyze with a visual tree debugger such as the XAML Spy or WinRT XAML Toolkit. You can also try tracing these various properties by walking the visual tree with the VisualTreeHelper class yourself.
I have a two stacked listboxes with data(first ListBox contains <10 elements, second may have up to 5000 elements),the elements of first listbox must be at top:
<ScrollViewer >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Listbox IsScrollable="False"/>
<Listbox Grid.Row="1" IsScrollable="False"/>
</ScrollViewer >
How I can improve perfomance of scrolling?
I know that I've lost virtualizingPanel when I call " ScrollViewer.SetVerticalScrollBarVisibility(sender as ListBox, ScrollBarVisibility.Disabled);"
But is there any way to enable it when I need two ListBoxes?
Why you don't want to use just one ListBox and set different Templates for different Data Types? You will not need to do any additional work to improve performance of scrolling.
Check this MSDN article Data Templating Overview, you will find one of the latest samples uses DataTemplateSelector and SL doesn't have this class, but you can find a lot of blog posts which trys to solve this problem in SL/WP: Implementing Windows Phone 7 DataTemplateSelector and CustomDataTemplateSelector. So if you will use this approach - you just need to be sure that you will bind to your collection and your collection will have a right order of elements: 10 elements from first ListBox, other elements from second ListBox.
I'm pretty new to WPF and C# and am trying to help out on some GUI stuff for work. We basically have 3 sections, a LHS (left hand side) [section 1], a RHS that has a top and bottom section [section 2 and section 3]. Looks like this
1 | 2
1 | -
1 | 3
They want a way to shrink each section with a button click. Currently the | and - are spacer items and can be dragged (Edit: this is done using a gridsplitter which they don't like). I did a little research and saw there are expander items and accordion items. I didn't know if either could be used for this scenario, and what would be the least hassle. In trying each just a bit, some additional questions for the controls come to mind since I'm not familiar with them.
Expander:
By shrinking section 1, would it make section 2 and 3 then take up the whole screen? Or can this only be done with an Accordion?
Is it hard/easy to change the <> icons to +- icons? If so, any tutorial out there?
Accordion:
Can the <> be changed to +-? If so, any tutorial out there?
Can the default color of blue be changed?
TIA
An Expander sounds like a suitable option for your situation. Fortunately it's included with WPF out of the box, unlike the Accordion control. But I found this question related to the Accordion control and thought it'd be useful for you to check out.
To change the appearance of the Expander toggle button you'll want to modify its control template. Changing the template to display plus or minus instead of arrows isn't too tough. If you visit the link you'll see you're going to want to change ExpanderToggleButton portion of the template.
Since you just want to change from using the arrows to using plus/minus signs you can simply change the Path data for collasped/expanded arrow. You can look here for more infortmation on drawing simple shapes with path.
Here is an example of someone modifying the control template of the Expander. It's for a different tweek in appearance, but it should be useful should you decide to go this route.
EDIT:
Really simple example (without the change in ToggleButton appearance) to get an idea of how to collaspe and save real estate:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColunmDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Expander Name="Section1" Grid.RowSpan="2" Grid.Colunm="0" ExpandDirection="Left">
<!-- Stuff goes here -->
</Expander>
<Expander Name="Section2" Grid.RowSpan="0" Grid.Colunm="1"
<!-- Stuff goes here -->
</Expander>
<Expander Name="Section3" Grid.RowSpan="1" Grid.Colunm="0"
<!-- Stuff goes here -->
</Expander>
</Grid>
You could use GridSplitter. The user can drag them to change the size. Not a click - a drag.
<GridSplitter Grid.Row="1" Grid.Column="1"
Width="3" Background="Purple" VerticalAlignment="Stretch" HorizontalAlignment="Center" ShowsPreview="False" >