I have a windows phone 7 project with a page that has the following structure:
I have scrollviewer and a stackpanel inside called main stackpanel
in the main stackpanel I have couple of stackpanels with horizontal orientation
the horizontal stackpanels has several textblocks each containing a single letter
sometimes the horizontal stackpanel contains more letters than it fits to the phone screen. From time to time I need to show a group of letters that are outside of the screen.
To be able to show these letters, I need to move the stackpanel, so the letters are becoming visible on screen. When I am finished the animation, the letters that are moved in to the screen are not visible at all.
What should I do to make it visible?
I added a screenshot and a pseudo xaml of my page to demonstrate the structure. I hope this will help!
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Disabled">
<StackPanel x:Name="MainStackPanel" Margin="12,0,12,-177" Grid.RowSpan="2" RenderTransformOrigin="0.5,0.5" >
<StackPanel x:Name="stackPanel" Orientation="Horizontal" Width="580" RenderTransformOrigin="0.5,0.5">
<StackPanel.RenderTransform>
<CompositeTransform/>
</StackPanel.RenderTransform>
<TextBlock Style="{StaticResource LetterStyle1}" VerticalAlignment="Stretch"><Run Text="e"/></TextBlock>
<TextBlock Style="{StaticResource LetterStyle1}" VerticalAlignment="Stretch"><Run Text="u"/></TextBlock>
... many more textblock each containing a letter
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource LetterStyle1}" VerticalAlignment="Stretch"><Run Text="e"/></TextBlock>
<TextBlock Style="{StaticResource LetterStyle1}" VerticalAlignment="Stretch"><Run Text="u"/></TextBlock>
... many more textblock each containing a letter
</StackPanel>
Fortunately, I managed to find the solution. The problem is that some of the horizontal stackpanel were wider then MainStackPanel.
Changing the MainStackPanel and the ScrollViewer to be as wide as the widest horizontal solves the problem.
<ScrollViewer VerticalScrollBarVisibility="Disabled" Margin="0,0,-106,0">
<StackPanel x:Name="MainStackPanel" Margin="12,0,12,-177" Grid.RowSpan="2" RenderTransformOrigin="0.5,0.5" >
Related
I would like to place my button always on the middle of the bottom frame of ScrollViewer. I am going to change both the size of window, and a size of ScrollViewer, but I want my button to be always as on the pictures.
Owing to the fact that i am following MVVM, I have just xaml. Basically, I would like to bind (live) the button top position from the pattern:
button.top = (scrollViewer.top + scrollViewer.height) - button.height/2
I would be grateful for your suggestions.
[EDIT] I forgot to add that all other controls are in grid rows and columns.
You can try to use Grid to achieve that. If you need to change the ScrollViewer size, just change ScrollGrid Grid size instead. To overlap bottom or top content, you can use negative margins for the button.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Border Background="Red"/>
<Border Background="Red" Grid.Row="2"/>
<Grid x:Name="ScrollGrid" Grid.Row="1">
<ScrollViewer></ScrollViewer>
<Button Width="100" Height="100" VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
</Grid>
</Grid>
So im trying to get my scroll bar to A only show up as needed and B show up only around my description text
Right now the scroll view is going from the top of the window to the bottom
<Window x:Class="WpfApplication3.DataWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataWindow" Height="300" Width="300">
<Grid>
<Label x:Name="lblTitle" Content="Label" HorizontalAlignment="Left" Margin="96,25,0,0" VerticalAlignment="Top" Width="186"/>
<Label x:Name="lblPublishDate" Content="Label" HorizontalAlignment="Left" Margin="96,53,0,0" VerticalAlignment="Top" Width="186"/>
<Image x:Name="imgPic" HorizontalAlignment="Left" Height="81" Margin="10,10,0,0" VerticalAlignment="Top" Width="81"/>
<ScrollViewer>
<TextBlock x:Name="tbDesc" HorizontalAlignment="Left" Margin="10,96,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="167" Width="272" Text="TextBlock" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" />
</ScrollViewer>
</Grid>
A grid tries to let it's children take up all availble space.
Your ScrollViewer is one of the children, so it will fill all available space by default.
There are a number of ways around this.
You could use a different panel type, one that doesn't try to stretch it's children to fill all available space. Based on what you're doing with excessively large margins, a Canvas might be suitable.
I would suggest reading this for a quick understanding of WPF's available Layout Panels : WPF Layouts - A Visual Quick Start
Another alternative is to give your Grid some Row Definitions, and specify that the row containing the ScrollViewer should be of a fixed size, or should be sized so it fits whatever size the child object wants (Height="Auto")
Or you could give your ScrollViewer a fixed height, and set it's VerticalAlignment property so it gets docked to either the top or bottom of the Grid.
Personally I would recommend the first option - reviewing WPF's layout system and determining a more approrpiate panel type for your layout. And if the most appropriate panel type is a Grid, then I would highly recommend using the RowDefinitions and ColumnDefinitions to give your Grid some structure, rather than trying to use excessively large Margins to position your controls.
You're pretty close, the problem appears to be an issue of layout. Because the controls are arranged in the grid without row and column definitions the scrollviewer is attempting to resize to the full size of the grid while the textblock is adhereing to its fixed size and margin. Try the following starting point and see if it helps:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="150"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Label x:Name="lblTitle" Content="Label" HorizontalAlignment="Left" Width="186"/>
<Label x:Name="lblPublishDate" Content="Label" HorizontalAlignment="Left" Width="186"/>
<Image x:Name="imgPic" HorizontalAlignment="Left" Height="81" Width="81"/>
</StackPanel>
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<TextBlock x:Name="tbDesc" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBlock"/>
</ScrollViewer>
</Grid>
I have a ScrollViewer which includes a lot of content (datagrids, stackpanels, textboxes, labels, etc...), and outside of it I want to add a button (PRINT), and it is important that the button is not part of the ScrollViewer. My goal is that the top 90% of my screen is the scrollviewer and the bottom 10% is a "frozen panel" that always shows the PRINT button, and this should remain true when maximized and minimized.
After having a lo of problems with 'the property content is set more then once' I realized I need to add both my ScrollViewer and the Button inside another container, so far the only one that seems to work is GRID - but honestly after you read this if you have anything else to recommend I am open to suggestions, I only used GRID because it seemed to almost give me what I wanted.
This is my code right now:
[Code]
<Window DataContext="{Binding PrintView, Source={StaticResource Locator}}" Width="900">
<Grid Height="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer Name="PrintView" Grid.Row="0" Height="Auto">
<StackPanel>
... a LOT of stuff ...
</StackPanel>
</ScrollViewer>
<Button Content="Print"
Margin="0,20,0,20"
Height="50"
Width="150"
FontSize="24"
FontWeight="Bold"
Grid.Row="1"
/>
</Grid>
</Window>
[Code]
When done like this my ScrollViewer doesn't have a Scrollbar so I see the first page but I cannot scroll down, also there is no PRINT button seen
One interesting test was to change the following:
<ScrollViewer Name="Apercu" Grid.Row="0" Height="600">
Now I see my scrollbar again (and I can scroll) and my PRINT button is beneth it and always visible (this is almost perfect) but when I maximumize my window the ScrollViewer stays 600 of height and as such well it doesn't acctually maximize (everything below the PRINT button is just white).
Any ideas? Is there another way I could specify my HEIGHTS or is there a different control I should be using (not GRID)?
Thanks,
Found it ...
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
And remove height from ScollViewer
I've tried almost every combination of alignments and margins, to no success. The ListBox is on a WPF page, which is bound to a frame on the main window.
The ListBox itself is fine. It aligns just as I expect it would. My ListBoxItem contains an Image and a TextBlock. The TextBlock gets cut off.
As you can see from the following image, things are mostly good.
The ListBox is appropriately offset from the left edge and the top of that blue box. The content Image and TextBlock are fairly centered and so is the ListBoxItem outline. This is on my development machine.
I thought the whole reason for using grids, grid lines, and alignment properties, was so we didn't have to set a hard coded size. That our controls would resize themselves. Which does actually work just fine for everything else.
But when I place this on a small screen, I get this:
The ListBox itself is still aligned correctly. But now the ListBoxItem is forced down. It's top alignment is still good, but the bottom is pushed down so we can't see the TextBlock or the bottom of the ListBoxItem.
Here's my XAML:
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1">
<Grid.RowDefinitions>
<RowDefinition Height="292*" />
<RowDefinition Height="30*"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="1" Name="lbButtons" Margin="2,0,0,1.5" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Visibility="Visible" >
<StackPanel Name="spListBoxItems" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Horizontal">
<ListBoxItem Margin="0,0,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="10,5,10,5">
<Image Source="/COBAN.CobanConsole.UI;component/Images/Buttons/Light/record48_light.png" />
<TextBlock Text="Record" Margin="5,5,0,0"></TextBlock>
</StackPanel>
</ListBoxItem>
</StackPanel>
</ListBox>
</Grid>
Not much to it. Any ideas on what's going on?
You're using * units on your grid row definitions. Those are relative measures: they just tell you what proportion of the space the rows can take up. If you need your listbox to have a specific height, you should change your second row to have an absolute size instead, like this:
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
I am trying to mimic the Sticky Notes application in Windows 7. In the original application, if you type text into a Sticky Note and the text becomes too large (vertically, as in number of lines) to fit in the window, the window automatically expands vertically, one line at a time, to allow for more room. In other words, where in a normal Textbox a vertical scrollbar would appear and the text would scroll down (so that the first line becomes invisible), in the Sticky Notes the textbox expands exactly enough to fit the text so that no scrollbar appears. The scrollbar still appears when you manually resize the window afterwards, of course.
If you have Windows 7 just open the Sticky Notes application and type a few lines in the sticky note until it enlarges.
I am trying to mimic this effect but I'm having no luck. The problem seems that the actual Window should resize, not just the Textbox (I don't think WPF works this way, that a resize of a child element can 'force' the parent element to become larger? At least not for a Window, right?).
The contents of the Window at this point are such:
<Window Background="Transparent" BorderBrush="Transparent">
<!-- Transparent border to draw dropshadow on -->
<Border Background="Transparent" BorderBrush="Transparent">
<!-- Grid with UI elements -->
<Grid Margin="5" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="27" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Stickynote header -->
<Border ... />
<!-- Content -->
<Border Grid.Row="1">
<TextBox Text="{Binding ContentText}" ... />
</Border>
</Grid>
</Border>
</Window>
Does anybody know how I can achieve this effect? Thanks!
Try the Window Property SizeToContent="Height"
Sample
<Window ...
MaxHeight="500"
SizeToContent="Height">
<Border Background="Transparent" BorderBrush="Transparent">
<Grid Margin="5" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="27" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="1">
<TextBox AcceptsReturn="True" MinHeight="100"/>
</Border>
</Grid>
</Border>
</Window>
Edit
To use it with the TransparentWindow you posted, add transparentWindow.SizeToContent = SizeToContent.Manual in OnDragDelta (TransparentWindow.cs)
private static void OnDragDelta(object sender, DragDeltaEventArgs e)
{
TransparentWindow transparentWindow = (TransparentWindow)sender;
Thumb thumb = e.OriginalSource as Thumb;
transparentWindow.SizeToContent = SizeToContent.Manual;
if (thumb != null && transparentWindow.WindowState == WindowState.Normal)
{
//...
}
}