I'm facing some elements' positioning problem in my wp 8.1 app (XAML/C#). I've read that to create a flexible layout, I should use the grid control.
Well, here is my XAML within the page element:
<Grid Style="{StaticResource LayoutGridCreateProfilStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Height="60" Fill="#F3A8E4F9" ></Rectangle>
<Rectangle Grid.Row="1" Height="40" Fill="Gray"></Rectangle>
<ListBox Grid.Row="2" Height="420" Background="Transparent"/>
<Canvas Grid.Row="3">
<Ellipse Height="100" Margin="0,0,0,0" Width="100" Fill="Black" Canvas.Left="152" Canvas.Top="10"></Ellipse>
</Canvas>
</Grid>
In the XAML designer, I'm actually seeing what I want and it looks like below:
And here is how it looks like on my Nokia Lumia 925:
As you can see, the ellipse is cut and I really cannot figure out how to place it as it should be and actually appears in the designer view.
Maybe somebody could help me with that ?
Thanks in advance !
The problem is that you are running out of height to show all the elements of your grid. The first three rows take up an accumulated height of 540 pixels. If the run time height available if 640 then you only have 100 left over for the last row of your grid.
But your Ellipse is offset 10 pixels from the top of the Canvas and so it needs a total of 110 (10 offset + 100 pixel ellipse height) in order to show fully. If your last row has less than 110 pixels of space then it will be truncated, as indeed it seems to be.
Related
My WPF Grid has 3 rows (Auto, *, *) and maxHeight set to 500. When there is no content for second or 3rd row, Grid still doesn't expand to its maxHeight.
XAML Code:
<Grid MaxHeight="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Button occupies 30 px-->
<Button Grid.Row="0" Content="SwitchGrid"/>
<ContentControl Grid.Row="1" Content="{Binding DG1}"/>
<ContentControl Grid.Row="2" Content="{Binding DG2}"/>
</Grid>
Problem Statement:
[Success] If both ContentControls are provided, they occupy equal space (~230 px) and Grid is shown to expand to MaxHeight=500 px.
[Failure] If either of the ContentControls are not provided, the other contentcontrol still occupies max ~230 px (this ContentControl can occupy 500 px, but due to Grid's restriction it occupies only 230 px and shows a scrollbar) and Grid doesn't expand to 500 px. Snoop reveals that one of the control control size is 0, but looks like Grid is still reserving space for it. I have seen this behavior even when the Grid is placed directly inside MainWindow, hence I dont this it is related to any other container.
What can I do to make sure Grid expands to MaxHeight if any of its children need it?
Thanks,
RDV
You can bind the row height to a string property..
<Grid MaxHeight="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Row1Height, FallbackValue=*}"/>
<RowDefinition Height="{Binding Row2Height, FallbackValue=*}"/>
</Grid.RowDefinitions>
<!-- Button occupies 30 px-->
<Button Grid.Row="0" Content="SwitchGrid"/>
<ContentControl Grid.Row="1" Content="{Binding DG1}"/>
<ContentControl Grid.Row="2" Content="{Binding DG2}"/>
</Grid>
Then you can update it whenever you want, for example..
public DG1 DG1 {
set{
// ..
Row1Height = value == null ? "0" : "*";
}
get{
// ..
}
}
I want the ScrollViewer to do only one thing - allow me to scroll. I don't want it to allow its Content to grow. Yet it does. How to prevent that?
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="a.png"/>
<Grid Grid.Row="1" Height="400"/>
</Grid>
</ScrollViewer>
If I comment out the ScrollViewer - the Image is small. If I leave the ScrollViewer - the Image grows. How to prevent that?
You would avoid stretching the Image by setting its Stretch property to None.
<Image Grid.Row="0" Stretch="None" .../>
The Grid and hence the Image element use the full width of the scrollable area. Since the default Stretch value is Uniform, the Image subsequently adjusts its height to keep its aspect ratio.
An equivalent, but simpler layout would be
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel>
<Image Stretch="None" Source="a.png"/>
<Grid Height="400"/>
</StackPanel>
</ScrollViewer>
I'm developing a Database system that needs to be resolution independent, some use screens that are still running at 1024 x 768, some use screens that are at 1920 x 1080 and others use everything in between.
I haven't done much work with WPF before so I'm sort of just starting out and attempting to get my head around height, widths and alignments.
What I have at the moment is one main window that holds an grid in which at the top there is a row for a label and some navigation buttons, as well as the time and the username of the person logged in. I then have a second row below that that holds a frame which I load pages into for the main navigation of the program.
In the pages I mainly use the grid layout, and occasionally the stack panel. One of the biggest problems I have come across is an issue like this;
In low resolutions this is common, where as in a higher resolution the buttons look fine;
This is the XAML code for the buttons within their parent grid;
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="HR" Margin="10" Click="RunHrSystem" FontSize="18.667" />
<Button Content="Companies" Margin="10" Click="RunCompSystem" FontSize="18.667" Grid.Row="1" />
<Button Content="People" Margin="10" Click="RunPeopleSystem" FontSize="18.667" Grid.Row="2" />
<Button Content="IT Management" Margin="10" Click="RunITManagementSystem" FontSize="18.667" Grid.Row="3"/>
<Button Content="Sales" Margin="10" FontSize="18.667" Grid.Row="4" />
<Button Content="Buying" Margin="10" FontSize="18.667" Grid.Row="5" />
<Button Content="Estimating" Margin="10" FontSize="18.667" Grid.Row="6"/>
<Button Content="Design" Margin="10" FontSize="18.667" Grid.Row="7"/>
</Grid>
Is there anything obvious I am doing wrong here that is preventing the buttons from resizing according to a lower resolution? As I say I get this throughout my program when using buttons, as well as the rectangle shape and in some situations labels, where the bottom of the label will be cut off too.
Currently, you are declaring RowDefinitions to use *, this tells the row to use the height as a percentage of the available space. Therefore, if your resolution changes, your row heights will change.
Instead, you want the RowDefinition to be the height of the content. In this case, when the resolution changes, the row heights will not change.
<RowDefinition Height="Auto"/>
It'd be a good idea to put the grid in a ScrollViewer, just in case the grid becomes larger than the screen.
<ScrollViewer>
<Grid>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
...
In your particular example, I would instead use a StackPanel.
<ScrollViewer>
<StackPanel>
<Button ...
I guess it's a bad practice to hide existing buttons in a non-visible area. The user should scroll for accessing bottom buttons. If you need to support the low-resolution monitor, an app should adjust to the current resolution.
I guess the best way is decreasing the margin, set * for RowDefinitions and limit grid height to prevent huge stretching.
I have a grid with two rows like
<Grid.RowDefinitions>
<RowDefinition Height="44" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0" HorizontalAlignment="Stretch" Orientation="Horizontal">
//...
</WrapPanel>
In the first row I am placing a WrapPanel with horizontal orientation. The elements within the WrapPanel are approx 40 heigth so it looks cool when there is only one line. However when the items wraps to two lines (say because the user decreases the width of the column with GridSplitter) then the WrapPanel correctly breaks into two line, but the second line is not shown, because the fixed 44 row height.
How can I achieve that the first row should be 44 or 88 according the WrapPanel's one line or two line layout?
Thanks in advance
It's a shame I did not figured out... "Auto" is the answer. Auto is never worked for me so maybe that's why it was not popped up in my mind first....
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0" HorizontalAlignment="Stretch" Orientation="Horizontal">
I would like the ScrollViewer of the page to be displayed when all the information cannot be shown on the screen (i.e. resize the window)
However, the ListBox here doesn't get a scroll and it gets sketch till the bottom of the page unless i set it to have a MaxSize. Is there a way to give priority to the ListBox to display its ScrollViewer before the one I have made?
what i have right now
http://i.imgur.com/bEJcz.png
what i would like to achieve, but i used a MaxHeight for the ListBox here.
Here's some my markup:
<ScrollViewer HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" Name="scrollViewer1" VerticalAlignment="Stretch" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Width="120" HorizontalAlignment="Left"></ComboBox>
<ListBox HorizontalAlignment="Left" Name="listBox" Width="120" Grid.Row="1" <!--MaxHeight="500"--> />
</Grid>
</ScrollViewer>
I know this question is old, but I had exactly the same problem and came up with a bit of a hack as a fix but its better than having the question unsolved.
Much of what I've read states that using things like StackPanel is bad in this case because the panel grows to fit the elements it holds. Normally this works fine because you can stick the StackPanel into a Grid and set the MinHeight and MaxHeight of the column/row and lock the controls in place. As soon as the ScrollView is added this kind of goes to hell. The answer above describes the problem well, but lacks a solution.
I tried many different types of Panels instead of a StackPanel but they all yield the same result. I decided that since my ListBox sits inside of a Grid, I needed to bind the MaxHeight of that grid location to some other value in the control to keep the ListBox from growing. The problem with this is that there is no element that you can bind straight to and get the exact height your looking for.
Enter the hack:
My height was just a tiny bit too big creating a weird always offscreen ListBox (in fact 36 pixels too large, which was the height of the label above the ListBox). So I implemented the IValueConverter:
class HeightToAdjustedHeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var height = (double) value - 33d;
return height < 360d ? 360d : height;
//360 being the minimum height allowed for the listbox
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
All I did after that was include it as a converter for the binding on MaxHeight (Note you need to name your usercontrol and bind to its x:Name):
<Grid Grid.Column="0"
Grid.Row="1"
VerticalAlignment="Top"
ClipToBounds="True"
MaxHeight="{Binding ElementName=AdHocUserControl, Path=ActualHeight, Converter={StaticResource HeightToAdjustedHeightConverter}}">
The only other alternative I can think of is to extend one of the panels and try to play with its growth behavior. I admit this is a hack, but it will work.
Try this
<ScrollViewer HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" Name="scrollViewer1" VerticalAlignment="Stretch" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Width="120" HorizontalAlignment="Left" ></ComboBox>
<ListBox HorizontalAlignment="Left" Name="listBox" Width="120" VerticalAllignment = "Top" Grid.Row="1"/>
</Grid>
</ScrollViewer>
Or you can also try this
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Width="120" HorizontalAlignment="Left" ></ComboBox>
<ListBox HorizontalAlignment="Left" Name="listBox" VerticalAlignment= "Top" Width="120" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
</Grid>
You have a logical inconsistency in your definitions.
The requirement as you put it: "I would like the scrollviewer of the page to be displayed when all the information cannot be shown on the screen [without using MaxHeight]" - a question arises: "How do you determine that 'all the information cannot be shown on the screen'?" or "At what point the ListBox should stop growing and show the scroll bar?".
From a WPF\Silverlight layout management logic, it does exactly what you want - when the sum of height of list box plus the height of the combo box is greater than the ViewportHeight of the scroll viewer - you get a scroll bar. That is possible only when you allow the ListBox to grow to it's desired size without scroll bars.
Dont set the MaxHeight on the ListBox, just use the star '*' notation in your RowDefinitions to get the relative sizing between your 2 controls correct.
Another solution:
<ScrollViewer HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" Name="scrollViewer1" VerticalAlignment="Stretch" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Width="120" HorizontalAlignment="Left"></ComboBox>
<ScrollViewer x:Name="scrollViewer" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<ListBox HorizontalAlignment="Left" Name="listBox" Width="120" Grid.Row="1" MaxHeight="{Binding ActualHeight, ElementName=scrollViewer}" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
</ScrollViewer>
</Grid>