Unwanted gap appears between GridSplitters - c#

I want to prevent a gap from appearing in my wpf window without modifying the behavior of the remaining splitters. Please note that the longest vertical splitter is supposed to be able to slide to the left; I just don’t want the gap to appear when it is moved. A comment has been added to the GridSplitters that make up the undesired gap. How do I prevent the gap from appearing? My XAML code is listed below:
<Window x:Class="MyAdvancedGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="480"
Width="600">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="250"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Row="0"
Grid.Column="2"
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
Grid.ColumnSpan="2"
Background="Black"
Height="5" /> <!-- A gap involves this splitter.-->
<GridSplitter Grid.Column="1"
HorizontalAlignment="Left"
Grid.RowSpan="2"
Background="Black"
VerticalAlignment="Stretch"
Width="5"/> <!-- A gap appears between this and the splitter above when this vertical splitter is moved to the left.-->
<GridSplitter Grid.Column="2"
Grid.Row="1"
Grid.ColumnSpan="1"
HorizontalAlignment="Right"
Grid.RowSpan="1"
Background="Black"
VerticalAlignment="Stretch"
Width="5"/>
</Grid>
</Window>

Its because your horizontal splitter is only spanning 2 columns.
If you want the horizontal splitter to span all 3 columns (left of the tall vertical splitter), then you should put it in Column 1, and make the ColumnSpan be 3.
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="250"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Row="0"
Grid.Column="1"
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
Grid.ColumnSpan="3"
Background="Black"
Height="5" /> <!-- see changes above.-->
<GridSplitter Grid.Column="1"
HorizontalAlignment="Left"
Grid.RowSpan="2"
Background="Black"
VerticalAlignment="Stretch"
Width="5"/>
<GridSplitter Grid.Column="2"
Grid.Row="1"
Grid.ColumnSpan="1"
HorizontalAlignment="Right"
Grid.RowSpan="1"
Background="Black"
VerticalAlignment="Stretch"
Width="5"/>
</Grid>

Related

Split items inside DockPanel

I want the 4 buttons (notification, printer, three dots and light/dark theme buttons) to the right of the window while the Humburger button and the TextBox should remain in the Left which will leave us with an empty middle.
XAML:
<DockPanel >
<materialDesign:ColorZone Panel.ZIndex="{Binding ElementName=DemoItemsListBox, Path=SelectedItem.ZIndex}"
Padding="16" materialDesign:ShadowAssist.ShadowDepth="Depth3" materialDesign:ShadowAssist.ShadowEdges="Bottom"
Mode="PrimaryMid" DockPanel.Dock="Top">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<DockPanel >
<ToggleButton DockPanel.Dock="Left" Style="{StaticResource MaterialDesignHamburgerToggleButton}" IsChecked="False"
x:Name="MenuToggleButton"/>
<StackPanel DockPanel.Dock="Left">
<materialDesign:ColorZone Mode="PrimaryLight" Padding="8 4 8 4" CornerRadius="2" Panel.ZIndex="1"
Margin="16 0 0 0"
materialDesign:ShadowAssist.ShadowDepth="Depth1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button IsDefault="True" Command="{Binding SearchEmploye}"
Style="{DynamicResource MaterialDesignToolButton}">
<materialDesign:PackIcon Kind="Magnify" Opacity=".56" />
</Button>
<TextBox Text="{Binding SearchEmp,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Grid.Column="1" Margin="8 0 0 0" materialDesign:HintAssist.Hint=""
materialDesign:TextFieldAssist.DecorationVisibility="Hidden" BorderThickness="0"
MinWidth="200" VerticalAlignment="Center" />
</Grid>
</materialDesign:ColorZone>
</StackPanel>
<materialDesign:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="White" Kind="Printer" Width="24" Height="24"/>
<materialDesign:PackIcon Width="24" Height="24" VerticalAlignment="Center" Kind="Bell" Margin="0 0 5 0"></materialDesign:PackIcon>
<materialDesign:PackIcon VerticalAlignment="Center" Kind="ThemeLightDark" Width="24" Height="24"></materialDesign:PackIcon>
<materialDesign:PopupBox Foreground="White" DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges" StaysOpen="True"/>
</DockPanel>
</Grid>
</materialDesign:ColorZone>
</DockPanel>
My goal is to have something like this (It's worth mentioning that my window is using SizeToContent)
I wouldn't use a DockPanel for something like that; I'd just use a Grid. (I'm just using placeholders to show where things go, so put your Hamburger button where I have put <Button>Hamburger</Button>) The overall structure I'd aim for would be:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="Green">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<Button>Hamburger</Button>
<TextBox>Search</TextBox>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Button>Print</Button>
<Button>Notification</Button>
<Button>Theme</Button>
<Button>DotDotDot</Button>
</StackPanel>
</Grid>
</Border>
<Grid Grid.Row="1">
<!-- Rest of screen -->
</Grid>
</Grid>

wpf grid and stackpanel fill

I have a grid with 2 rows one for a name and button and the other for output.
I want the first row to stretch the full width and the button to align to the right.
Wondering what I am missing as I thought the stackpanel would fill the width.
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" >
<TextBox Name="NameTextBox" MinWidth="150" HorizontalAlignment="Stretch"/>
<Button Margin="10,0" Name="AlertButton" Content="Say Hello" HorizontalAlignment="Stretch" />
</StackPanel>
<TextBox Name="OutpuTextBox" MinLines="5" Grid.Row="1" Grid.Column="0"/>
</Grid>
</Window>
Horizontal StackPanel ignores horizontally alignment of its children. You can change your layout to 2 columns and put Button in the second column of first row and set bottom TextBox to span across 2 columns
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Name="NameTextBox" MinWidth="150" HorizontalAlignment="Stretch"/>
<Button Margin="10,0" Name="AlertButton" Content="Say Hello" HorizontalAlignment="Stretch" Grid.Column="1" />
<TextBox Name="OutpuTextBox" MinLines="5" Grid.Row="1" Grid.ColumnSpan="2"/>
</Grid>

WPF basic binding

I know this has been asked quite a few times, but no matter how many tutorials I read, I simply cannot understand it. I have a grid with three ColumnDefinitions that can be resized via two GridSplitters. What I want is another grid below it with three ColumnDefinitions that resize as the top grid is being resized (much alike the UI in a program like iTunes). The reason I want separate grids is because eventually, each grid will be its own object and will need drag and drop properties. Here is the Xaml I have written if anyone wants to see what I'm looking at.
<Canvas Width="400" Height="15" Background="AntiqueWhite">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="400" Name='Maingrid'>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="140" MinWidth="50"/>
<ColumnDefinition Width="116" MinWidth="50"/>
<ColumnDefinition Width="144" MinWidth="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<GridSplitter Grid.Column="0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="Black"
ShowsPreview="True"
Width="2"
/>
<GridSplitter Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="Black"
ShowsPreview="True"
Width="2"
/>
<TextBlock Text="Song" Grid.Column="0" Width="30"/>
<TextBlock Text="Song" Grid.Column="1" Width="30"/>
<TextBlock Text="Song" Grid.Column="2" Width="30"/>
</Grid>
</Canvas>
<Canvas Width="400" Height="15" Background="RosyBrown" Margin="58,168,59,138">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="400">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="140" MinWidth="50"/>
<ColumnDefinition Width="116" MinWidth="50"/>
<ColumnDefinition Width="144" MinWidth="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<TextBlock Text="Song" Grid.Column="0" Width="30"/>
<TextBlock Text="Song" Grid.Column="1" Width="30"/>
<TextBlock Text="Song" Grid.Column="2" Width="30"/>
</Grid>
</Canvas>
Also as a final note, I've looked at endless amounts of tutorials and guides on data binding and my 17 year old brain just can't seem to wrap my head around it. If I could understand how to make a textblock be bound to a variable in my C# codebehind (aka: not setting the textblock's text property in the codebehind, but simply changing the contents of a string), I'd be able to be so much more productive. Thank you to anyone who can help me, I know this question has been asked a million times.
In your c# codebehind, create a property:
private string _songTitle;
public string SongTitle { get { return _songTitle; } set { songTitle = value; } }
In your xaml, create a binding:
<TextBlock Text="{Binding SongTitle}" />
Set the DataContext for your binding (you could put this in the Window.Loaded event)
this.DataContext = this;
Set your property in your code
SongTitle = "Some words and stuff";
That's about it. It can get more complicated, but that's the basics.
This is a way to do it without code behind. Just give your first column definitions names, then bind the lower column definitions widths' to the width of the appropriate column definitions in the first grid. Clean and simple, no code behind to mess with:
<Canvas Width="400" Height="15" Background="AntiqueWhite">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="400" Name='Maingrid'>
<Grid.ColumnDefinitions>
<ColumnDefinition Name="Grid1Col1" Width="140" MinWidth="50"/>
<ColumnDefinition Name="Grid1Col2" Width="116" MinWidth="50"/>
<ColumnDefinition Name="Grid1Col3" Width="144" MinWidth="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<GridSplitter Grid.Column="0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="Black"
ShowsPreview="True"
Width="2"
/>
<GridSplitter Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="Black"
ShowsPreview="True"
Width="2"
/>
<TextBlock Text="Song" Grid.Column="0" Width="30"/>
<TextBlock Text="Song" Grid.Column="1" Width="30"/>
<TextBlock Text="Song" Grid.Column="2" Width="30"/>
</Grid>
</Canvas>
<Canvas Width="400" Height="15" Background="RosyBrown" Margin="58,168,59,138">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="400">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Width, ElementName=Grid1Col1}" MinWidth="50"/>
<ColumnDefinition Width="{Binding Width, ElementName=Grid1Col1}" MinWidth="50"/>
<ColumnDefinition Width="{Binding Width, ElementName=Grid1Col1}" MinWidth="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<TextBlock Text="Song" Grid.Column="0" Width="30"/>
<TextBlock Text="Song" Grid.Column="1" Width="30"/>
<TextBlock Text="Song" Grid.Column="2" Width="30"/>
</Grid>
</Canvas>

Avoid inheritance of opacity between nested Grids

I have a Grid with its background as black an opacity to 0.5 and in it is there another grid with opacity to 1 and background as White. But the inner grid still shows as its opacity was 0.5
<Grid Grid.ColumnSpan="2" Grid.RowSpan="2" Background="Black" Opacity="0.5" Visibility="{Binding Alertar, Converter={cnv:boolToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="2*"></RowDefinition>
<RowDefinition Height="5*"></RowDefinition>
<RowDefinition Height="2*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Background="Black" Opacity="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="1.5*"/>
</Grid.RowDefinitions>
<Rectangle Grid.ColumnSpan="3" Grid.RowSpan="2" Fill="Black" Opacity="1"/>
<TextBlock Grid.Column="1" Margin="0,15,0,0" Text="{Binding ReporteInconsistencias}" />
<Button Grid.Column="1" Grid.Row="1" Content="Aceptar" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10"/>
</Grid>
</Grid>
I'm trying to emulate a win8 alert screen there is another way to do this? or How to prevent this inheritance? why this happen?
A little messy but this should work i think. Basically controls are stacked. So having the grid come after the first grid it shouldn't effect the opacity. May need to be tweaked, but something along the lines of this should work:
<Grid Grid.ColumnSpan="2" Grid.RowSpan="2" Visibility="{Binding Alertar, Converter={cnv:boolToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="2*"></RowDefinition>
<RowDefinition Height="5*"></RowDefinition>
<RowDefinition Height="2*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.RowSpan="3" Background="Black" Opacity="0.5" />
<Grid Grid.Row="1" Background="Black" Opacity="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="1.5*"/>
</Grid.RowDefinitions>
<Rectangle Grid.ColumnSpan="3" Grid.RowSpan="2" Fill="Black" Opacity="1"/>
<TextBlock Grid.Column="1" Margin="0,15,0,0" Text="{Binding ReporteInconsistencias}" />
<Button Grid.Column="1" Grid.Row="1" Content="Aceptar" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10"/>
</Grid>
</Grid>

Grid in ScrollViewer doesn't scroll horizontally

I think I'm missing something simple here... how do I get a Grid inside a ScrollViewer to scroll horizontally? I've enabled HorizontalScrollMode, and the content is definitely long enough that it runs off the screen, but it doesn't scroll. Here's the offending code (this ScrollViewer is the lone content of a row of the LayoutRoot Grid):
<ScrollViewer Grid.Row="1" VerticalScrollMode="Disabled"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollMode="Enabled">
<Grid Margin="120,0,0,100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="240"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="240"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="240"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="240"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Download" HorizontalAlignment="Center" Margin="0,0,0,10"/>
<local:BandwidthMeter Grid.Row="1" x:Name="PolicyDown" Grid.Column="0"/>
<TextBlock Grid.Column="2" Text="Upload" HorizontalAlignment="Center"/>
<local:BandwidthMeter Grid.Row="1" x:Name="PolicyUp" Grid.Column="2"/>
<TextBlock Grid.Column="4" Text="Download" HorizontalAlignment="Center"/>
<local:BandwidthMeter x:Name="ActualDown" Grid.Row="1" Grid.Column="4"/>
<TextBlock Grid.Column="6" Text="Upload" HorizontalAlignment="Center"/>
<local:BandwidthMeter x:Name="ActualUp" Grid.Row="1" Grid.Column="6" />
<TextBlock Grid.Column="7" Text="Campus-wide bandwidth usage" HorizontalAlignment="Center"/>
<Image Grid.Column="7" Grid.Row="1" Margin="80,0,0,0" Source="[image URL]" Stretch="UniformToFill"/>
</Grid>
</ScrollViewer>
Add the property HorizontalScrollBarVisibility="Auto" to your ScrollViewer.

Categories