I have a requirement to show 3 panel with GridSplitter as separators in grid in WPF and C#. Also Closing options for each panel.
Plese see image to better understand design:
When user close the left panel , now the middle panel stretch from left , same-thing like right panel also. In run time i'll dock again these panels.
I'm tried to hidden/collapsed Closed panel and closed panel related splitterm but no luck.
Any suggestions or ideas would be most welcome?
Edited
I required 5 column definitions including splitters (3 panels and 2 splitters). Design code is
<Grid Margin="0,120,0,20" Name="panelGrid">
<!--
1)Browser
2)Player
3)Chat
-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<DockPanel Name="webBrowserPanel" Grid.Column="0"
Visibility="Visible" Background="Green" Height="auto">
<Button HorizontalAlignment="Center" Width="20"
Height="20" Click="leftBut"></Button>
</DockPanel>
<GridSplitter Name="sp1" Grid.Column="1" HorizontalAlignment="Center"
VerticalAlignment="Stretch" Background="Red"
ShowsPreview="True" Width="5"/>
<Grid x:Name="grid1" Grid.Column="2" AllowDrop="True"
Background="#FF807272"/>
<GridSplitter Name="sp2" Grid.Column="3" HorizontalAlignment="Center"
VerticalAlignment="Stretch" Background="Red"
ShowsPreview="True" Width="5"/>
<Grid x:Name="chatGrid" Grid.Column="4" Visibility="Visible"
Background="DarkOrange" >
<Button HorizontalAlignment="Center" Width="45" Height="20"
Click="righCli">
</Button>
</Grid>
</Grid>
Is this what you mean?
<Grid x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" x:Name="leftColumn"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" x:Name="rightColumn"/>
</Grid.ColumnDefinitions>
<!-- u can also use DockPanel within a grid -->
<DockPanel>
<!-- this border is under the splitter and can't be seen-->
<Border Background="Red" DockPanel.Dock="Right" Width="5"/>
<Border Background="#AA0">
<Button VerticalAlignment="Top" Click="Button_Click_1" Content="x"/>
</Border>
</DockPanel>
<Border Background="#0AA" Grid.Column="1">
<Button VerticalAlignment="Top" Click="Button_Click_2" Content="reset"/>
</Border>
<!-- u can also use grid within a grid -->
<Grid Grid.Column="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- this is also an extra column for splitter -->
<Border Background="Red" Grid.Column="0"/>
<Border Background="#A0A" Grid.Column="1">
<Button VerticalAlignment="Top" Click="Button_Click_3" Content="x"/>
</Border>
</Grid>
<GridSplitter Grid.Column="0" Width="5" x:Name="leftSplitter"/>
<!-- by setting the correct margin you hide the underlying red border -->
<GridSplitter Grid.Column="1" Width="5" x:Name="rightSplitter" Margin="0,0,-5,0"/>
</Grid>
code behind:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
leftColumn.Width = new GridLength(0);
leftSplitter.Visibility = System.Windows.Visibility.Collapsed;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
leftColumn.Width = new GridLength(40);
rightColumn.Width = new GridLength(40);
leftSplitter.Visibility = System.Windows.Visibility.Visible;
rightSplitter.Visibility = System.Windows.Visibility.Visible;
}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
rightColumn.Width = new GridLength(0);
rightSplitter.Visibility = System.Windows.Visibility.Collapsed;
}
it can improved using converters to bind splitters visibilities and columndefinitions widths to a property in view model.
Related
I have a GridSplitter which is dragable and both columns resize accordingly. I have a button which can hide the right column but I am looking to have another press of the button to show the right column again and still be dragable.
I have tried to use a ToggleButton but the GridSpiltter is fixed using it and is not dragable.
How can I have a button to show/hide a column and still be adjustable by the user?
GridSplitter:
<GridSplitter x:Name="rightSplitter"
Grid.Column="1"
Width="15"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Background="Transparent"
ShowsPreview="True" />
Column Definitions:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="300" x:Name="rightColumn"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
Button:
<Button Width="50" Height="50" HorizontalAlignment="Right" x:Name="Details_Toggle" Focusable="False">
<StackPanel>
<Image Source="controls/details.png" />
</StackPanel>
Button Click C#:
private void deatilsShowHide(object sender, RoutedEventArgs e) {
rightColumn.Width = new GridLength(0);
rightSplitter.Visibility = System.Windows.Visibility.Collapsed;
}
Since you are making the right items collapsed, it will make the control not to be present in the panel.
Instead of making the Visibility Collapsed. We can set the width as 10 when button is clicked and when again clicked we can revert it back to original width. At the same time, we can also drag the GridSplitter.
private void deatilsShowHide(object sender, RoutedEventArgs e)
{
if(rightColumn.Width == new GridLength(10))
{
rightColumn.Width = new GridLength(300);
}
else
{
rightColumn.Width = new GridLength(10);
}
}
Xaml:-
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="300" x:Name="rightColumn"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Column="0" Background="AliceBlue">
<Button Width="50" Height="50" HorizontalAlignment="Right" x:Name="Details_Toggle" Focusable="False" Click="Details_Toggle_Click">
<StackPanel>
</StackPanel>
</Button>
</StackPanel>
<GridSplitter x:Name="rightSplitter"
Width="15" Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
ShowsPreview="True" />
<StackPanel Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" >
<Button Content="test" Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75"/>
</StackPanel>
</Grid>
I have this built and I add text boxes to it programmatically and update after each addition but the scrollViewer never becomes scrollable just grayed out arrows. I'm only adding textBoxes to one of the stackPanels, could that be it? If so is there some work around for that? I'd appreciate any help, I've spent much too long on this silly problem.
<ScrollViewer x:Name="scrollViewerMain" VerticalScrollBarVisibility ="Visible" HorizontalAlignment="Center" Height="368" Width="410" VerticalAlignment="Top" Margin="150,309,150,-35.5">
<Grid HorizontalAlignment="Left" Height="368" VerticalAlignment="Center" Width="410" ScrollViewer.CanContentScroll="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="stackPanelPlayerNames" Grid.Column="0" Height="368"/>
<StackPanel x:Name="stackPanelWins" Grid.Column="4" Height="368"/>
<StackPanel x:Name="stackPanelHours" Grid.Column="5" Height="368"/>
<StackPanel x:Name="stackPanelKills" Grid.Column="1" Height="368"/>
<StackPanel x:Name="stackPanelDeaths" Grid.Column="2" Height="368"/>
<StackPanel x:Name="stackPanelRatio" Grid.Column="3" Height="368"/>
</Grid>
</ScrollViewer>
Your Grid should not have a fixed height. If your Grid (inside your ScrollViewer) is ALWAYS 368 pixels tall, and that your ScrollViewer is bigger than 368 pixels tall, then there is always no overflow.
There is DockPanel with three child controls placed side by side in a horizontal manner:
1) TreeView
2) RichTextBox
3) Grid
RichTextBox lies in middle of TreeView and Grid. I made RichTextBox the last child of DockPanel and set LastChildFill attribute to True. Now since Grid can be closed at run time, I want the RichTextBox to occupy all the space that became empty after the Grid is closed. But if the Grid is again shown the RichTextBox should contract from Right hand side to allow the Grid to fit in. How to achieve this? I'm new to WPF. Also, how to hide the Grid? Here is the XAML.
<DockPanel Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" LastChildFill="True">
<Border BorderThickness="1" DockPanel.Dock="Left" Height="Auto" HorizontalAlignment="Stretch" Margin="1" VerticalAlignment="Stretch" Width="Auto" CornerRadius="0" BorderBrush="#FF646464">
<TreeView Name="TV" Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Border>
<Border Name="Notification_Pane" BorderThickness="1" DockPanel.Dock="Right" Height="Auto" HorizontalAlignment="Stretch" Margin="1" VerticalAlignment="Stretch" Width="Auto" CornerRadius="0" BorderBrush="#FF646464">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="Notification" Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Top" Background="LemonChiffon" Grid.Row="0" Grid.Column="0"/>
<Button Name="btn_Close" Content="X" Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="LemonChiffon" Height="Auto" Width="Auto" Grid.Row="0" Grid.Column="1" Padding="10,0,10,0" BorderThickness="0" Cursor="Hand" Focusable="True" IsHitTestVisible="True" ClickMode="Release" Click="Button_Click" />
<ScrollViewer Height="Auto" Name="ScrollViewer" Width="Auto" Margin="0" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<StackPanel CanVerticallyScroll="True" Height="Auto" Name="Notification_Panel" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
<Border BorderThickness="1" Height="Auto" HorizontalAlignment="Stretch" Margin="1" VerticalAlignment="Stretch" Width="Auto" CornerRadius="0" BorderBrush="#FF646464">
<RichTextBox Name="rtb" Height="Auto" Width="Auto" Grid.Row="2" HorizontalAlignment="Stretch" Grid.Column="1" Margin="0" />
</Border>
</DockPanel>
You can use Grid.Visibility property to show and hide the grid.
The following code should do the job:
private void Button_Click(object sender, RoutedEventArgs e) //X Button click event.
{
//grid is the name of our Grid Control we want to hide.
grid.Visibility = System.Windows.Visibility.Collapsed;
}
to show the grid again you should use the following code:
grid.Visibility = System.Windows.Visibility.Visible;
The RichTextBox control will always fit in the DockPanel Control.
In my Windows Store app (c#) i have Popup:
<Popup x:Name="LoginPopup" HorizontalAlignment="Center" VerticalAlignment="Center" Width="400" Height="300" IsOpen="{Binding Path=LoginPopupIsOpen}">
<Popup.ChildTransitions>
<TransitionCollection>
<PopupThemeTransition />
</TransitionCollection>
</Popup.ChildTransitions>
</Popup>
And when Popup IsOpen I need handle events only on Popup and freeze all another UI (including AppBar). It is possible without creating full screen popup with little work area?
You can do it in the xaml.cs file by using two properties.
In the event handler for the popup you are creating you can include the following two lines
this.IsEnabled = false;
this.ApplicationBar.IsVisible = false;
in the event handler where you want to close the popup, you can revert the properties back to their original values.
this.IsEnabled = true;
this.ApplicationBar.IsVisible = true;
I was also facing similar problem and used this to handle that.
private void AlertMessage_Opened(object sender, object e)
{
UIBlock.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
private void AlertMessage_Closed(object sender, object e)
{
UIBlock.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
My popup name was AlertMessage and I attack opened and closed events with it and place a border in xaml which covers whole screen, and handle is visibility through these events.
<Border Name="UIBlock" Grid.Row="0" Grid.RowSpan="3" Background="#AAFFFFFF" Visibility="Collapsed">
</Border>
And remember to place this border before popup
I have made small popup using below code.Please try this.
<Grid Background="Black" Opacity="0.7" Visibility="Collapsed" x:Name="gdalert" Height="{Binding Height, ElementName=gdfullpage}" Width="{Binding Width, ElementName=gdfullpage}">
<Popup x:Name="settingpopup" Width="350" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
<Border x:Name="settingbdrmain" Grid.Row="1" BorderThickness="0" Width="350" CornerRadius="15" >
<Grid x:Name="gdsubshape" Margin="0,10,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="dddf" FontSize="20" Text="" HorizontalAlignment="Center" TextAlignment="Center" FontFamily="Arial" FontWeight="Bold" TextWrapping="Wrap" ></TextBlock>
<TextBlock x:Name="txtsettingalert" Text="" FontSize="20" TextAlignment="Center" Width="300" FontFamily="Arial" TextWrapping="Wrap" Foreground="Black" Grid.Row="1" ></TextBlock>
<Border x:Name="settingbdr" Width="350" Grid.Row="2" Height="1" Background="Red" BorderBrush="Black" >
</Border>
<Grid x:Name="btnpanel" Grid.Row="3" Height="60">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto">/ColumnDefinition>
</Grid.ColumnDefinitions>
<Button x:Name="settingok" Grid.Column="0" Height="50" HorizontalAlignment="Left"VerticalAlignment="Center" MinHeight="20" Width="170" Content="OK" FontSize="24" Foreground="Green" ></Button>
<Border x:Name="settingsubbdr" Grid.Column="1" BorderBrush="Green" Height="Auto" Width="1" ></Border>
<Button x:Name="sl" Grid.Column="2" Height="50" HorizontalAlignment="Right" VerticalAlignment="Center" MinHeight="20" Width="170" Content="Cancel" FontSize="24" Foreground="Green" ></Button>
</Grid>
</Grid>
</Border>
</Popup>
To Open Use :- popname.IsOpen = true; gdalert.Visibility = Visibility.Visible;
To Close popname.IsOpen = false; gdalert.Visibility = Visibility.Collapse;
I am running into a layout issue which I am not sure how to solve. Here is how my xaml looks like,
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid x:Name="abc" Grid.Row="0" Grid.Column="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0"></Button>
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
</Grid>
</Grid>
<Grid Grid.Row="0" Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0"></Button>
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
</Grid>
</Grid>
</Grid>
Now the layout of the above xaml is exactly as what I want. However, I have one additional requirement. At runtime I need to make grid "abc" collapsable. And the other grid needs to fill the entire width. If I use star sizing width then if "abc" is collapsed it behaves more like hidden than collapsed. Collapse seems to work with Auto sized widths but then it doesn't give me propotional sizing as required. Is there a way to accomplish this. Note, I only have access to Grids, StackPanels, and Canvas for layout of my items (no DockPanel). Please let me know of any ideas along with any code snippets. Thanks.
Hard tell your intent in the layout, but here is a sample to get you started.
I changed the ColumnDefintion width from * to Auto in the Click event and set the Visibility to Collasped for "abc" Grid. I used the second button to change these values for test purposes, and I removed an extra level of Grid that is not needed.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnToCollapse" Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid x:Name="abc" Grid.Row="0" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0"></Button>
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
</Grid>
<Grid Grid.Row="0" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Click="Button_Click" />
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
</Grid>
</Grid>
Here is the button click event:
private bool _toggle = true;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (_toggle)
{
ColumnToCollapse.Width = GridLength.Auto;
abc.Visibility = Visibility.Collapsed;
_toggle = false;
}
else
{
ColumnToCollapse.Width = new GridLength(1, GridUnitType.Star);
abc.Visibility = Visibility.Visible;
_toggle = true;
}
}
Had the same problem, only made worse by having a splitter in a middle third column.
Basically I wound up binding the column widths (each of them) to properties that return auto in one mode and star in the other mode. Make sure you implement INotifyPropertyChange for the properties and call the onchange helper for both column property names when you change the flag controlling the layout.