Grid in ScrollViewer doesn't scroll horizontally - c#

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.

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>

Align TextBlock in Button / StackPanel correctly

I try to align the TextBlocks to the left.
The button should take the rest of the area (Up to the picture).
How can I do this?
This is a UWP / C# App.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid VerticalAlignment="Center" HorizontalAlignment="Left">
<Button Background="Transparent" HorizontalAlignment="Stretch">
<StackPanel HorizontalAlignment="Left">
<TextBlock x:Name="TextBlock1" TextWrapping="Wrap" Text="Name1"/>
<TextBlock x:Name="TextBlock2" TextWrapping="Wrap" Text="Name2" />
</StackPanel>
</Button>
</Grid>
<StackPanel Grid.Column="1" Grid.Row="0" HorizontalAlignment="Right">
<Button Height="50" Width="50" Background="Transparent" Click="Button_Click">
<Image x:Name="ImageFavorit" Source="/Assets/Stern/VGrau64.png"/>
</Button>
</StackPanel>
</Grid>
Firstly you should replace your ColumnDefinitions to this:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
And secondly remove HorizontalAlignment="Left" from your Grid then you can achieve to what you want:
<Grid VerticalAlignment="Center">
<Button Background="Transparent" HorizontalAlignment="Stretch">
...
Also it seems that you need to set VerticalAlignment="Center" of your StackPanel too:
<StackPanel Grid.Column="1" Grid.Row="0"
HorizontalAlignment="Right" VerticalAlignment="Center">
Update: Based on your comment that you want the text on the left side Set the HorizontalContentAlignment="Left" of the Button:
<Button Background="Transparent" HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left">

Equal spacing between controls

I want to place image and text under image as below. The height of the rows have to be equally divided. How can this work if I want images to size accordingly?
<Grid.ColumnDefinitions>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="40*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
</Grid.RowDefinitions>
<Image Grid.Column="1" Grid.Row="0" Source="pack://application:,,,/WpfApplication5;component/led.green.off.png" HorizontalAlignment="Center">
</Image>
<TextBlock Grid.Column="1" Grid.Row="1" Text="Turret Power" ></TextBlock>
<Image Grid.Column="1" Grid.Row="2" Source="pack://application:,,,/WpfApplication5;component/toggle.sheath.DOWN.png" HorizontalAlignment="Center">
</Image>
<TextBlock Grid.Column="1" Grid.Row="3" Text="Off" ></TextBlock>
<Image Grid.Column="1" Grid.Row="4" Source="pack://application:,,,/WpfApplication5;component/toggle.sheath.DOWN.png" HorizontalAlignment="Center">
</Image>
<TextBlock Grid.Column="1" Grid.Row="5" Text="Off" ></TextBlock>
<Image Grid.Column="1" Grid.Row="6" Source="pack://application:,,,/WpfApplication5;component/toggle.sheath.DOWN.png" HorizontalAlignment="Center">
</Image>
<TextBlock Grid.Column="1" Grid.Row="7" Text="Off" ></TextBlock>
<Image Grid.Column="1" Grid.Row="8" Source="pack://application:,,,/WpfApplication5;component/toggle.sheath.DOWN.png" HorizontalAlignment="Center">
</Image>
<TextBlock Grid.Column="1" Grid.Row="9" Text="Off" ></TextBlock>
<Image Grid.Column="1" Grid.Row="10" Source="pack://application:,,,/WpfApplication5;component/toggle.sheath.DOWN.png" HorizontalAlignment="Center">
</Image>
<TextBlock Grid.Column="1" Grid.Row="11" Text="Off" ></TextBlock>
</Grid>
If I do the above, the images are big and go over the window
You're missing 2 <RowDefinition> in <Grid.RowDefinitions> (according to your usages of Grid.Row)
You don't have to put a weight in your row/column definitions if they're all the same, and you don't even have to set Height if the value is *, since this is the default (you can remove Height="10*" from each <RowDefinition>)
Maybe you'll want to have some column definitions set with Width="Auto", but I'll leave that to you.

Using template of pushpin, created in XAML, in code

I created a template for pushpin (image and some text) by XAML. However i don't know how to use it in my C# code.
Here is my temlate:
<maps:Map x:Name="myMap" Width="446" Loaded="myMap_Loaded">
<maps:Map.Layers>
<maps:MapLayer>
<maps:MapOverlay>
<toolkit:Pushpin x:Name="myPushpin">
<toolkit:Pushpin.Template>
<ControlTemplate TargetType="toolkit:Pushpin">
<Grid Background="WhiteSmoke">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<Image x:Name="pushpinImg" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Height="30" Width="30"/>
<TextBlock x:Name="pushpinText" Grid.Row="0" HorizontalAlignment="Left" Grid.Column="1" Foreground="Green" TextWrapping="Wrap"/>
</Grid>
</ControlTemplate>
</toolkit:Pushpin.Template>
</toolkit:Pushpin>
</maps:MapOverlay>
</maps:MapLayer>
</maps:Map.Layers>
</maps:Map>

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>

Categories