WPF Create a slide out panel - c#

I don't know how this works technically but my requirement is as follows. I have a DataGrid and to input data into the DataGrid, I want a panel at the bottom of the DataGrid that slides out on a button click showing input options. Except, as the panel slides out, the DataGrid has to resize vertically as well. Can someone throw some light on how I can implement this?

You should be able to use a StackPanel with 2 children, your grid and your panel. Set the initial height of your panel to 0. Once the button is clicked, set the height to whatever you need it to be (e.g., MyPanel.Height = 20). You might want to wrap the grid in a ScrollViewer in case that is needed.
<StackPanel Orientation="Vertical">
<ScrollViewer Height="Auto" VerticalAlignment="Stretch">
<Grid Height="*" VerticalAlignment="Stretch" />
</ScrollViewer>
<ContentControl x:Name="MyPanel" Height="0" />
</StackPanel>
You might need to experiment with VerticalAlignment and Height="Auto" or Height="0" to get the layout you want.

You can use Expander. Please look at the following code snippet.
<DockPanel>
<Expander DockPanel.Dock="Bottom">
<StackPanel>
<TextBlock Height="25"></TextBlock>
<TextBlock Height="25"></TextBlock>
<TextBlock Height="25"></TextBlock>
</StackPanel>
</Expander>
<Border BorderBrush="LightGreen" BorderThickness="2">
<DataGrid/>
</Border>
</DockPanel >

Related

WPF ScrollViewer is not working

I want to add scroll view to my program and I tried ScrollView control but that don't take effect. It's my first time dealing with scrolls please help me :).
My xaml Code:
<DockPanel Grid.Row="1" Background="#FF695887">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="795">
<Canvas Name="zemelapis" Height="Auto" Width="Auto">
<Image Name="pav_kelias" />
<Image Name="car1" />
</Canvas>
</ScrollViewer>
</DockPanel>
Because these 2 images is not fitting here I need a scroll for them. Maybe I should use ScrollBar?
My program example: https://gyazo.com/a4ba7e4d5004632e2229a87e686c4c09
, as you can see bottom image is not fitting in range of window.
You have specified Auto as Height and Width. This implies that the Canvas will fill the height available to it.
From the documentation:
Auto sizing behavior implies that the element will fill the height
available to it.
In this case the available height is the height of the ScrollViewer.
If you want the Canvas to be bigger, and hence the ScrollViewer to scroll, you should set a height on Canvas that is bigger than the height of ScrollViewer.
So, for example:
<DockPanel Grid.Row="1" Background="#FF695887">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="795">
<Canvas Name="zemelapis" Height="1000" Width="Auto">
<Image Name="pav_kelias" />
<Image Name="car1" />
</Canvas>
</ScrollViewer>
</DockPanel>
If you want your ScrollViewer to work easily, use a Grid instead of a Canvas:
<DockPanel Background="#FF695887">
<ScrollViewer >
<Grid Name="zemelapis">
<Image Name="pav_kelias" Source="acteurs.png"/>
<Image Name="car1" Source="public.jpg"/>
</Grid>
</ScrollViewer>
</DockPanel>
As explain by Domysee, Canvas gives you total control of the layout. Grid however will automatically adjust its size depending on the content.
See http://www.wpf-tutorial.com/panels/introduction-to-wpf-panels/

Not able to stretch an inner StackPanel

Usingthe setup below, I can color the whole width of the window purplish. The inner stack panel is chartreusian and shifted to the left.
<StackPanel HorizontalAlignment="Stretch"
Orientation="Horizontal"
Background="BlueViolet"
Height="70">
<StackPanel HorizontalAlignment="Left"
Orientation="Horizontal"
Background="Chartreuse" >
I was expecting that if I changed the horizontal alignment of the inner stack panel to streched, it'd fill out all the width as well but that doesn't happen. I've tried both right and streched alignments and it seems that it's not affecting the width of the inner control.
According to the posts I've found that is the way to achieve it (and it certainly worked for the outer control). What can I be missing? I've removed the other controls declared in the outer panel (i.e. all the siblings to the chartreusily colored one) with no difference.
A StackPanel will provide to its content as much space as required but also only as few as necessary.
If you want to fill exactly the width of the window, just replace the outer StackPanel by a Grid
If you want the StackPanel to fill at least the whole with, you can bind the MinWidth to its parent ActualWidth:
<StackPanel HorizontalAlignment="Stretch"
Name="parent"
Orientation="Horizontal"
Background="BlueViolet"
Height="70">
<StackPanel HorizontalAlignment="Stretch"
MinWidth="{Binding Path=ActualWidth, ElementName=parent}"
Orientation="Horizontal"
Background="Chartreuse" >
</StackPanel>
</StackPanel>
I spent a lot of time in the past struggling with stackpanels.
Here is what happens:
Your outer stackpanel (#1) has horizontal orientation, what means, that it can fill as many childs as needed, stacking them horizontally. Whenever child is rendered, there is a dialog between child and parent:
--(Child) I want to render and I have this size. Can you provide me enought space?
--(Parent) I'll do calculations and we'll see how it goes.
In case of nested stackpanels your outer stackpanel tries to stretch and demands infinite width and it's parent grid gives him just all the width he has.
But the purpose of stackpanel is to be infinite in one direction and if it's child asks for infinite width (what inner stackpanel does, when you set horizontal alignment to stretch) then we just give him minimum amount of width, since otherwise they would grow out of control and consume all memory on your PC.
So this is just an artistic view on what happens and it can be inaccurate.
Update:
Putting things simply: You can't set horizontal alignment to stretch for a child of a stackpanel with horizontal orientationand you can't set vertical alignment to stretch for a child of a stackpanel with vertical orientation.
Well, you can, but it won't stretch, because if it could, then it would have stretched infinitely
Answer: Replace inner or outer stackpanel with a grid. The fact, that you are using 2 nested stackpanels with a same orientation says that you are doing something wrong. To be honest, the only application of stackpanel, in my opinion, is inside of a scrollviewer. In other cases it's better to use WrapPanel.
I too struggle with this and provide this solution incase someone else is looking for a similar solution.
My particular issue was I needed to get the Hamburger Menu to the top and out of the SplitView. I was then trying to get the stackpanel to fill out the whole region below. This works well and a screen shot below shows what it looks like.
Hope this helps and happy to be corrected if this is not best practise.
<Grid Background="{ThemeResource AppBarToggleButtonCheckedPointerOverBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Height="50" Grid.Row="0">
<StackPanel Background="Gray" Height="50" HorizontalAlignment="Stretch">
<Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content=""
Width="50" Height="50" Background="Transparent" Click="HamburgerButton_Click"/>
</StackPanel>
</StackPanel>
<SplitView Grid.Row="1" x:Name="MySplitView" DisplayMode="Overlay" IsPaneOpen="False"
CompactPaneLength="1" OpenPaneLength="150" VerticalAlignment="Stretch">
<SplitView.Pane >
<StackPanel >
<StackPanel Orientation="Horizontal">
<Button x:Name="LogIn" FontFamily="Segoe MDL2 Assets" Content="" Width="50" Height="50" Background="Transparent"/>
<TextBlock Text="Log In" FontSize="18" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="SignUp" FontFamily="Segoe MDL2 Assets" Content="" Width="50" Height="50" Background="Transparent"/>
<TextBlock Text="Sign Up" FontSize="18" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</SplitView.Pane>
<SplitView.Content>
<Grid VerticalAlignment="Stretch">
</Grid>
</SplitView.Content>
</SplitView>
</Grid>
Menu close:
Menu open:

Force Size on a Viewbox's Children

So I have a rather interesting question. I have a viewbox that has a few elements in it (a custom user control for an image, a canvas, a label, and a textbox). What I want is to try and have all elements scale with the viewbox, but I want the label and the textbox to have a "Max Size." I have tried using a max width and height on these controls but they seem to ignore it. If someone could take a look at my code below an slap me for what I am doing wrong that would be appreciated.
<Viewbox Name="myViewBox" Stretch="Uniform">
<!--Grid used to track mouse movements in this element for other reasons -->
<Grid Name="grdViewboxGrid" MouseMove="trackMouse">
<Canvas Name="cvsViewboxCanvas" MinWidth="270" MinHeight="270"
VerticalAlignment="Top" HorizontalAlignment="Center"
Panel.ZIndex="1" Background="Black"
MouseUp="Canvas_MouseUp"
MouseMove="Canvas_MouseMove">
<Grid>
<!--Would rather not post here for Intellectual Property reasons-->
<!-- Extension of the image control -->
<CustomImageUserControl />
<Grid>
<Grid Width="{Binding LabelWidthPercentage}"
MaxWidth="50"
Height="{Binding LabelHeightPercentage"
MaxHeight="26"
SnapsToDevicePixels="True" VerticalAlignment="Top"
HorizontalAlignment="Left" Margin="5" IsHitTestVisible="False">
<Label Name="lblViewboxLabel" HorizontalAlignment="Left"
Padding="5,5,5,0" Margin="0,5,0,0"
Style="{x:Null}"
Content="{Binding lblContent}" />
</Grid>
<Grid>
<Grid Width="{Binding TextBoxWidthPercentage}"
MaxWidth="156"
Height="{Binding TextBoxHeightPercentage}"
MaxHeight="45"
SnapsToDevicePixels="True" Vertical="Top"
HorizontalAlignment="Right" Margin="5" IsHitTestVisible="False">
<Border Style="{DynamicResource CustomBorder}" />
<Grid>
<Textbox Name="txtViewboxTextBox" Text="{Binding txtViewbox}" />
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</Canvas>
</Grid>
</Viewbox>
If I am not including something that is needed please let me know and I will update my question. Any help would be greatly appreciated this is now day 4 on this issue sadly :-(
I am not sure why you need so many overlapping Grids, but I hope that I can answer your question nevertheless:
In order to have the label left of the text box and to assign a maximum width to each of these two controls, use a Grid with two columns and set the MaxWidth property for each column. Then, assign the label to the left column (the one with index 0) and assign the text box to the right column (index 1). The corresponding code fragment looks like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="30"/>
<ColumnDefinition MaxWidth="156" MinWidth="30"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" x:Name="lblViewboxLabel" HorizontalAlignment="Left" Foreground="Yellow"
Padding="5,5,5,0" Margin="0,5,0,0"
Style="{x:Null}"
Content="{Binding lblContent}" />
<TextBox Grid.Column="1" x:Name="txtViewboxTextBox" Text="{Binding txtViewbox}" Background="Orange"/>
</Grid>
I also have assigned a MinWidth to the right column; this is necessary to make sure that the text box does not completely disappear if it contains no text.

Fill StackPanel inside DockPanel

This should be easy: how can I stretch StackPanel inside the DockPanel, so that it would fill the whole parent's content and also maintain it's HorizontalAlignment?
Example:
<DockPanel LastChildFill="True">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Background="Yellow">
<Button Height="30">Button1</Button>
<Button Height="30">Button2</Button>
</StackPanel>
</DockPanel>
In this example the StackPanel's width is the same as the combined width from both buttons (and the background here is yellow), but the remaining space in DockPanel stays white. Looks like the LastChildFille property isn't working in my example.
I think by setting HorizontalAligment to Center on the StackPanel you are overriding the behavior of the DockPanel to fill the whole space with the StackPanel.
When i understand your question right, you want that the full space is yellow and the stackpanel with buttons is centered in the middle. Then you should wrap the StackPanel inside a Grid.
<DockPanel LastChildFill="True">
<Grid Background="Yellow">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Height="30">Button1</Button>
<Button Height="30">Button2</Button>
</StackPanel>
</Grid>
</DockPanel>

how to make an element stretch the entire width of its parent

in my Windows Phone application I have such structure:
<Grid Width="460" Height="77" Margin="-10,0,0,0" Background="#FFD20000" HorizontalAlignment="Center">
<StackPanel Width="Auto" Orientation="Horizontal" HorizontalAlignment="Center" >
<ToggleButton x:Name="ToggleButton_A" Content="Info" Width="150" Style="{StaticResource ToggleA}" Click="ToggleButton_A_Click" />
</StackPanel>
</Grid>
In my case I have a button in the center of conteiner. But I need to make it fill all place of it's parent conteiner, how can I implement this?
Simply remove the stackpanel, and the ToggleButton will fill all the grid. Everything is about using the right container for the right task.

Categories