i want to add squares to a panel and have them wrapped like the wrap panel.
I then want to make each square horizontally resizable individually, but when it is resized vertically, i need it to affect all the items in it's row.
Basically, I'd want all items in a row to always share the same height, but give the user a method of choosing this height (of course, each row can have its own height, and when squares wrapped to a new row they will need to inherit the new height).
Btw, those "squares" are just user controls or data template applied to a listbox items source. Can i use the same binding on a wrap panel, ad maybe i need to choose a different solution?
Thank you
you can try and put each "rectangle" in a Grid with one row and one column, and then use SharedSizeGroup on the RowDefinition. Be sure to also put Grid.IsSharedSizeScope="True" on the container:
<WrapPanel Grid.IsSharedSizeScope="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition SharedSizeGroup="Group1" />
</Grid.RowDefinitions>
<Button Height="40" Content="Hello" />
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition SharedSizeGroup="Group1" />
</Grid.RowDefinitions>
<Button Content="Hello2" />
</Grid>
</WrapPanel>
Related
I have a stackpanel in a grid row with the row height set to auto.
I add user controls at runtime and the height resizes fine, when removing the user controls the height does not reduce though. I have tried to clear the stackpanel children, remove them one by one and also implemented IDisposable in each user control but when the child count shows zero the height has not reduced.
Sample XAML below, any help would be welcomed please?
<Grid x:Name="TestGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Test Header" Style="{StaticResource SubHeaderTextBlock}" />
</StackPanel>
<StackPanel x:Name="ChildItems" Grid.Row="1" />
</Grid>
Replace the StackPanel with a Grid. Grids stretch and retract better than StackPanels.
Instated of removing put Visibility to Collapsed
I have got the following XAML:
<StackPanel HorizontalAlignment="Center">
<Image Name="logo" Source="logo.png" Margin="0,0,0,50"/>
<ScrollViewer>
<Dashboard_Control:AlignableWrapPanel x:Name="wrapPanel"/>
</ScrollViewer>
<TextBlock FontWeight="Bold" HorizontalAlignment="Center" x:Name="txtBottomText"></TextBlock>
</StackPanel>
I would like that the wrapPanel is scrollable only, so that the txtBottomText control will always be at the bottom as you scroll, and the logo image control will always be at the top - essentially only allowing the wrapPanel to be scrollable.
I have tried adding a ScrollViewer as shown above, however it never shows. I even tried adding a property to always have the vertical scrollbar, however it appears without letting me scroll (the scrollbar is disabled).
I suspect that this is because my wrapPanel's content is dynamically generated at run-time like so:
wrapPanel.Children.Add(content);
Any ideas what I can do to fix this?
It's not because of your wrapPanel's content. but because you're using a StackPanel to contain everything.
StackPanels grow indefinitely in the direction determined by their Orientation property. By default, that's vertically.
In your case, that makes the ScrollViewer "think" it has enough available space to stretch itself to accomodate its content, instead of activating the scroll bars. So it simply gets bigger as the WrapPanel inside gets bigger, pushing the TextBlock down.
To avoid this, you need to use a different Panel that is able to properly assign the available space to each control. Like a Grid.
<Grid HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Name="logo" Source="logo.png" Margin="0,0,0,50"/>
<ScrollViewer Grid.Row="1">
<Dashboard_Control:AlignableWrapPanel x:Name="wrapPanel"/>
</ScrollViewer>
<TextBlock Grid.Row="2" FontWeight="Bold" HorizontalAlignment="Center" x:Name="txtBottomText"></TextBlock>
</Grid>
I usually say that StackPanels tend to be overused :P They're practical and easy to use, but they have a bunch of quirks and limitations that make them not suitable for many situations, like this one.
EDIT: Make sure, also, that the Grid is not contained inside another vertical StackPanel, a Grid row with Height set to Auto, or something like that.
If the Height of your WrapPanel exceeds the height of the control or window where you have put the controls, the Textblock below the Wrap Panel inside the Stack Panel is put after the Wrap panel and so it is below the scroll area.
To be able to leave the Textblock always visible you have two means:
1) limit the height of your Wrap panel
2) Use a container like a Grid with 3 rows instead of the stack panel and put the Row Heights of the Grid respectively to
Auto, *, Auto so that the image on top and the textblock on bottom use the space of their content and the Scroll panel uses all the space remaining
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.Row ="0" Source="myimage.jpg" />
<ScrollViewer Grid.Row="1">
<WrapPanel Height="1200" Width="600">
<TextBlock>Ciao sono io</TextBlock>
</WrapPanel>
</ScrollViewer>
<TextBox Grid.Row="2" TextWrapping="Wrap" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="IO c'ero" />
</Grid>
You have to set a fixed heigh to your scrollviewer - if not, the scrollviewer takes as much space as he needs, in order to show the complete content of its children.
Solutions:
Set the Height property of your scollviewer
Use a grid instead of a stackpanel an set the first and third rowheight to auto
Please help me in this issue of scroll bar visibility in WPF listview.
I have a listview inside a Content Control.
This Content Control is inside a User Control.
This User Control is inside a TabItem.
The listview has around 12 columns to display, which exceeds the window width.
I tried so many ways to show the horizontal scroll bar in the listview.
Below shown is the XAML of the Outer UserControl [width is not set for this outer usrCrtl]
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" /> // Here I have a custom content control
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<MyCustomContentControl Grid.Row=1 VerticalAlignment="Stretch"......>
<TabControl>
<TabItem Header="One" Name="Tab1">
<my:usrAControl /> // I have listview inside this userctrl
</TabItem>
</TabControl>
<TabControl Header="Two" Name="Tab2" />
</MyCustomContentControl>
</Grid>
Now below is the usrAControl XAML details
<UserControl x:Class="MyProject.MyModule.usrAControl"
MinWidth="640">
// Again inside another custom user control as its child.
<usrBControl>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" /> // here another headers
<RowDefinition Height="*" /> // here my listview placed
</Grid.RowDefinitions>
<ListView ScrollViewer.HorizontalScrollBarVisibility="Auto" Grid.Row="1"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=Width}">
// Around 12 columns which exceeds window width
</ListView>
</Grid>
</usrBControl>
</usrAControl>
I tried with lot of combination.
I initially put a scrollviewer control inside the tabitem and placed usrAControl inside it.
But it did not work.
But I want the listview should show its both scroll bars. Is any way to do it.?
Without seeing more code, my guess would be that the MinSize="640" is your problem: the ListView gets enough space from its container so it doesn't show the scroll, but the container gets clipped.
And you should get rid of the ListView Width binding, it's completely redundant.
I have just started to experiment with gridsplitters and have stumbled across a very weird behaviour and I cannot seem to fix it. Apparently the others have similar issues (according to google), but there were no helpful comments.
I have a grid with 2 rows. On start up the bottom one has a Hight of 250. The top row takes the rest with *. When I resize the rows with the splitter the behaviour is as expected for the top row. But when I drag the splitter upwards and past the program window, the content of the bottom row will drop out of the window (=move downwards until it is gone). I'd expect that I cannot make each row larger than the parent container.
<Grid x:Name="grid_main" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition MinHeight="250" Height="250"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<GridSplitter x:Name="splitter"
ResizeDirection="Rows" Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Width="Auto"
Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="0" ResizeBehavior="BasedOnAlignment" />
<Grid Grid.Column="0" Grid.Row="0">
</Grid>
<Grid Grid.Column="0" Grid.Row="1">
</Grid>
</Grid>
This is my code. The content of both rows is again hosted in grids and has been removed for the sake of simplicity. Again: Resizing for the top row works fine. But the bottom row can be resized to infinity. It works as expected if I hard-code a MaxHeight. But that has to depend on the window size.
Try changing your second RowDefinition to the following:
<RowDefinition MinHeight="250" MaxHeight="{Binding ElementName=grid_main, Path=ActualHeight}" Height="250"/>
This will ensure that the row height will not exceed the window size.
Richard's solution didn't work for me (the ActualHeight of the grid expanded past the window size along with the row height).
Using Snoop, I found that the ActualHeight of an ancestor ContentPresenter wasn't increasing. Thus the following bottom row definition worked for me, although I was still seeing issues if I set MinHeight on either the top or bottom rows:
<RowDefinition Height="430"
MaxHeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=ActualHeight}"/>
This problem only occurs because the second row has an absolute Height. If you actually want an absolute Height value try Richards's solution. Otherwise, just use a relative Height (e.g. 2*) on the second row as well.
Grigory Zhadko's answer is good to me.
I had a problem with this code
gridBase.RowDefinitions[1].Height = (GridLength)gridLengthConverter.ConvertFrom("1");
gridBase.RowDefinitions[3].Height = (GridLength)gridLengthConverter.ConvertFrom("1");
and I fixed it like this
gridBase.RowDefinitions[1].Height = new GridLength(0.1, GridUnitType.Star);
gridBase.RowDefinitions[3].Height = new GridLength(0.1, GridUnitType.Star);
and the grid converter works perfectly
I have a expander and TextBlock.
It at times overlaps for spaces.
I want the expander BringToFront.
But no such property in WPF.
How to do it?
Is seems you are using the Canvas Panel for positioning your Expander and TextBlock.
First of all: Don't use a Canvas, it's oldstyle and not flexible enough. Use one of the other Panels (i.e. Grid) to layout your Controls. Then the problem should be gone.
If you must use a Canvas and you want to prevent overlapping, you can use the Panel.ZOrder attached property. You should also set the Background property of the Expander to something opaque like "White". By default the Background property has the null-value, which means transparent.
If the issue is a design time issue:
WPF will put the last item in the XAML on top. For instance if I had this:
<TextBlock Text="one"/>
<TextBlock Text="Two"/>
TextBlock "Two" would be displayed in front of "One" because it is last in the XAML.
If it's a runtime issue bochja had it right up top with the Panel.ZOrder.
It would probably be easiest to use a Grid, so the element order doesn't matter.
Eg:
<Grid DataContext="{Binding CurrentRequest,ElementName=root}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="These labels"/>
<Label Grid.Row="0" Grid.Column="0" Content="Will overlap"/>
<Label Grid.Row="1" Grid.Column="0" Content="Next row"/>