WPF wrappanel: manage horizontal and vertical behaviour - wpf

is there any way to obtain this layout using a WPF Wrappanel? B and C in the pictures should be vertically aligned in horizontal mode and horizontally aligned in vertical mode. Letters orientation must be preserved.
In pictures, from [Horizontal] to [Vertical]:
Horizontal
Vertical
I've tryed:
<wrappanel>
<A/>
<wrappanel>
<B/><C/>
</wrappanel>
</wrappanel>
but its behaviuor is unpredictable. Thank you in advance.

If you just want to be in proper alignment, you can just use Grid like this.
That way B and C will always have same width and height, whenever you resize window.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Content="A" Grid.Column="0" Grid.RowSpan="2" />
<Button Content="B" Grid.Column="1" Grid.Row="0"/>
<Button Content="C" Grid.Column="1" Grid.Row="1"/>
</Grid>

Related

Grid layout and expanding controls (TextBox)

I seem to not understand the layout behavior in my application. In the following sketch I have a TextBox that expands as text is being entered. How can I prevent that from happening and have the Height stay constant and get a Scrollbar instead? The size of the right TextBox should the size the left three TextBoxes take.
Initial state:
After adding several values:
Here's the XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="LightBlue">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" Text="One" Margin="5" />
<TextBox Grid.Row="1" Grid.Column="0" Text="Two" Margin="5" />
<TextBox Grid.Row="2" Grid.Column="0" Text="Three" Margin="5" />
<TextBox
Grid.RowSpan="3" Grid.Column="1" Margin="5"
AcceptsReturn="True"
Text="Hello World!"
VerticalScrollBarVisibility="Auto"
/>
</Grid>
<Rectangle Grid.Row="1" Fill="Blue" />
</Grid>
Simple Answer
Assuming that the font size and margins of the TextBoxes are going to remain constant, and that the TextBoxes on the left are single-line only, you can just set a fixed height for the top RowDefinition:
<Grid.RowDefinitions>
<RowDefinition Height="84" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
Complicated Answer
If the left TextBoxes are multiline, or if the font size or margins can change, then you'll have to get a bit more complicated. I don't think there's an existing Panel that can handle that, you'd have to manually set the Height of the right TextBox to match the sum of the ActualHeight + Margin.Top + Margin.Bottom for all of the left TextBoxes. This would need to be done whenever SizeChanged was raised on any of the left TextBoxes.

Layout problem with autogenerated DataGrid in WPF/XAML

I've got a problem with WPF/XAML. I can't figure out how to let the left Grid (with a centered image inside and backgroud color) grow its height, depending on the autogenerated height on the datagrid on the right.
They both are presented in a global grid. If I set a fixed height on the corresponding row, the autogenerated datagrid shows a cruel vertical line, depending on the fixed row-height I set before.
layout with row-height on auto
layout with fixed row-height, but with ugly line at the bottom
<!--ElementR0C1-->
<Grid Name="test">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<!--Width ElementsC1-->
<ColumnDefinition Width="160"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="500"/>
</Grid.ColumnDefinitions>
<!--START-->
<Label Grid.Row="0" Grid.Column="0" Style="{StaticResource L1}" VerticalAlignment="Top">Process</Label>
<Grid Grid.Row="1" Grid.Column="0" Background="DDDDDD">
<Image Margin="0,30,0,0" Height="64" Width="64" Source="../../Resources/ok.png" Name="imgJobs" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
<DataGrid x:Name="grdJobs" Grid.Row="0" Grid.Column="2" Grid.RowSpan="2" Width="500">
-- some stuff here
</DataGrid>
</Grid>

WPF: Inner content wont scroll

I have a Window with a Grid inside:
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="70" />
<RowDefinition Height="*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding ChildViewModel.View}" />
<DockPanel Grid.Row="1" Visibility="{Binding SearchResultViewVisibility}">
<GridSplitter DockPanel.Dock="Top" Background="LightGray" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Top" IsTabStop="False"/>
<Views:SearchResultView DataContext="{Binding SearchResultViewModel}" />
</DockPanel>
<UserControls:GradientBackgroundControl Grid.Row="2" Height="25">
<Validators:FocusSummaryControl x:Name="FocusSummary" ValidateOnlyFocusedElement="False" />
</UserControls:GradientBackgroundControl>
</Grid>
The ContentControl gets a UserControl with this Grid set:
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Row="0" Grid.ColumnSpan="4">
<StackPanel>
...
</StackPanel>
</ScrollViewer>
The problem now is, that the ScrollViewer in the UserControl doesn't scroll. The content of the UserControl set to the ContentControl is heigher and the overflow ist just hidden.
If I am not wrong, StackPanel requires a Height to be set for scroll functionality to work because StackPanel, by design, grows in one direction (based on Orientation).
To confirm whether this is the cause of your problem, please test by setting the height of StackPanel to a fixed height. Alternately, you may want to replace the StackPanel with say DockPanel and see the behaviour. Also there is a ScrollViewer.CanContentScroll property that you may want to fiddle with.
Let us know the result of this test.
I think you need to rearrange things a little bit. My suggestions (I'm sure there are infinite variations that would work):
First, add a new row to your grid (Height="Auto") and set the height of your top row (with your ContentControl in it) to "*"
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="70" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
Second, move your GridSplitter out of the DockPanel. Put the splitter in row 1 and the dockpanel in row 2.
<ContentControl Grid.Row="0" Content="{Binding ChildViewModel.View}" />
<GridSplitter Grid.Row="1" Background="LightGray" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Top" IsTabStop="False" ResizeBehavior="PreviousAndNext"/>
<DockPanel Grid.Row="2" Visibility="{Binding SearchResultViewVisibility}">
<Views:SearchResultView DataContext="{Binding SearchResultViewModel}" />
</DockPanel>
Note that you'll probably also have to set the ResizeBehavior for your GridSplitter as shown above. I hope this will get you close to what you want.

Silverlight Grid does not fill

I have Border control defined like so:
<Border Background="Azure" Grid.Row="2">
<ContentControl Width="Auto" Height="Auto" Regions:RegionManager.RegionName="MainContent" />
</Border>
I can see Azure background in whole area
Now I inject my view into this ContentControl (it's PRISM). View looks like this..
<toolkit:BusyIndicator IsBusy="{Binding IsBusy}">
<Grid Margin="10" DataContext="{Binding}"
infBehaviors:RegionPopupBehaviors.CreatePopupRegionWithName="ViewPopup"
infBehaviors:RegionPopupBehaviors.ContainerWindowStyle="{StaticResource PopupStyle}">
<!--Define rows in a grid-->
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Define columns in a grid-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="65" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
Now when I place new UserCOntrol on top of my Grid - I expect it to cover whole "Azure" area. But I only see overlay with size of my data entry form. It seems that second grid does not "fill" ContentControl - only takes as much space as needed. How do I force it to fill? I set Auto column and row - thinking they will stretch but no..
EDIT:
Screenshot from Silverlight Spy.. It shows that ContentControl from Shell covers whole area but grid inside totally ignores my "*" sizes. Also it does work in design mode - it stretches to whole design area...
Make sure you have HorizontalContentAlignment and VerticalContentAlignment of the ContentControl set to Stretch. ^_^
e.g.
<Border Background="Azure" Grid.Row="2">
<ContentControl HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Width="Auto" Height="Auto" Regions:RegionManager.RegionName="MainContent" />
</Border>

WPF: Problem with overlapping controls and grid column widths

I have a problem regarding a parent grid with a control in it that overlaps a tabcontrol.
I need the child grid (in the tab control) to resize its columns according to the overlapping control.
Specifically, when the overlapping control is resized (due to resize of the window for example) the child grid inside the tabcontrol needs to resize its columns so that the child controls inside the tabcontrol grid isn't overlapped by the control that overlaps the tabcontrol.
I sincerely hope someone here knows a solution for this problem, I've been fighting with it for days :)
Thanks in advance!
Best regards,
Req
edit: In response to the comments below:
Absolutely - I figured I should have, but seeing that I was/am at work I didn't have the code handy. But I can write up a similar example of the XAML.
<Grid Name="parentGrid" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<TabControl Name="tabCtrl" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="2">
<TabItem Name="tabItem1">
<Grid Name="tabCtrlGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" /> <!-- This is the column I want to resize according to the overlapping image control below -->
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Button Name="someChildControl" Grid.Column="1" Grid.Row="0" />
</Grid>
</TabItem>
</TabControl>
<Image Name="overlappingImg" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Grid.RowSpan="2" /> <!-- whenever the screen/window is resized, the parentGrid resizes, and thus resizing this overlapping image. -->
</Grid>
What needs to happen is that column 0 in the tabCtrlGrid needs to resize its width to fit the width of the overlapping area of the image. That way someChildControl is never overlapped by the image, regardless of how it's resized.
Hopefully that makes it a little more clear :)
How does this look?
<Grid Name="parentGrid" Background="LightGray">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Aqua"/>
<TextBlock Text="Tab controller" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"/>
<Rectangle Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Aqua"/>
<TextBlock Text="Up down nav" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<Grid Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle HorizontalAlignment="Left" VerticalAlignment="Top" Width="130" Height="160" Fill="BlanchedAlmond"/>
<TextBlock Text="CoverArt" HorizontalAlignment="Left" VerticalAlignment="Top" Width="130" Height="160"/>
<Rectangle Grid.Column="1" Fill="LightGray" />
<TextBlock Text="Tab content" Grid.Column="1" />
</Grid>
</Grid>

Resources