components does not scale properly - c#

For my WPF project in C#, I have to create a menu state which should look like image below
So far, I have created
XAML Code for this window:
<UserControl x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800">
<Grid Background="White" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="125"/>
<RowDefinition Height="100"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200*"/>
<ColumnDefinition Width="400*"/>
<ColumnDefinition Width="200*"/>
</Grid.ColumnDefinitions>
<!-- title -->
<Label Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" FontFamily="Franklin Gothic Heavy">
<Viewbox>
<TextBlock>Title</TextBlock>
</Viewbox>
</Label>
<!-- menu -->
<Grid Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="15"/>
<RowDefinition Height="50"/>
<RowDefinition Height="15"/>
<RowDefinition Height="50"/>
<RowDefinition Height="15"/>
<RowDefinition Height="50"/>
<RowDefinition Height="15"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
<Button Grid.Row="2" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
<Button Grid.Row="4" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
<Button Grid.Row="6" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
<Button Grid.Row="8" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
</Grid>
</Grid>
</UserControl>
Problem with this window is this components (label and buttons with their contents) does not scale properly. What I want is, when I resize the window I want this components to be proportional to window. Not sure if the grid layout is problem, but how can I fix this components scale properly.
EDIT:
Ok, so I followed your instructions and I like the results (everything seems to scale good enough),
but I have two more minor problems:
1) With a new changes to XAML code, my last button is colliding with the south border of the window, which is not what I want. What I want is an empty space with size of almost exactly (if possible) or close space, like between Label "Title" and north border of the window.
I found solution by defining a new line at the end <RowDefinition Height="*"/>. Not sure if this is a correct way to go.
2) Thus, so far I understand that , 1, 2*,... multiplies the current size. However, it seems I still feel like I don't fully understand it. Currently, I am asking myself, how can I now change the size (width or height in some case) of the button components inside grid layout?
Finally, do I change properties for the size directly to button or via grid layout?
Here is the code for a new window.
<UserControl x:Class="TypeRacer_Client.state.MenuState"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800">
<Grid Background="White" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- title -->
<Label Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" FontFamily="Franklin Gothic Heavy">
<Viewbox>
<TextBlock>Title</TextBlock>
</Viewbox>
</Label>
<!-- menu -->
<Grid Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="15"/>
<RowDefinition Height="*"/>
<RowDefinition Height="15"/>
<RowDefinition Height="*"/>
<RowDefinition Height="15"/>
<RowDefinition Height="*"/>
<RowDefinition Height="15"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
<Button Grid.Row="2" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
<Button Grid.Row="4" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
<Button Grid.Row="6" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
<Button Grid.Row="8" Grid.Column="0" FontFamily="Franklin Gothic Medium">
<Viewbox><TextBlock>State</TextBlock></Viewbox>
</Button>
</Grid>
</Grid>
</UserControl>

Use star sizing (ratios) to size your grid's rows etc. Like , 2, 4* etc. This will make the rows and columns keep the same ratios, no matter what size the window is, like this:
<RowDefinition Height="*" />
<RowDefinition Height="2* /> //this will be 2x the previous row's height
Style the buttons for consistent width/height/other properties etc.
<Style TargetType="Button" x:Name="SomeButtonStyle">
<Setter Property="Width" Value="90" />
</Style>
then , for each button you want the same height/width/whatever property:
<Button Style="{StaticResource SomeButtonStyle}" />
This will keep you from putting a width, height or font etc. in EVERY button you made, and makes it much faster to change the value in one place, instead of every button.

Related

Drop event not firing on wpf grid

I'm trying to develop an ancient form of chess, Chaturaji, as an assignment for school. I've got some very basic xaml setup that should allow me to drag and drop an image element within a grid.
<Page
x:Class="Projectg.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Projectg"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid AllowDrop="True" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition Width="900">
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="900"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid Background="Transparent" x:Name="grdGrid" AllowDrop="True" Grid.Column="1" Grid.Row="1" Drop="grdGrid_Drop" >
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image CanDrag="True" x:Name="Image" Canvas.ZIndex="1" Height="80" Width="80" Grid.Row="0" Grid.Column="0" Source="/images/boat.png" DragStarting="Boat_DragStarting" Drop="Boat_Drop" DragOver="Image_DragOver" ></Image>
<Image CanDrag="True" Canvas.ZIndex="1" Height="80" Width="80" Grid.Row="1" Grid.Column="0" Source="/images/horse.png" ></Image>
<Image Canvas.ZIndex="1" Height="80" Width="80" Grid.Row="2" Grid.Column="0" Source="/images/elephant.png" ></Image>
<Image Canvas.ZIndex="1" Height="80" Width="80" Grid.Row="3" Grid.Column="0" Source="/images/crown.png" ></Image>
<Image Canvas.ZIndex="1" Height="80" Width="80" Grid.Row="0" Grid.Column="1" Source="/images/pawn.png" ></Image>
<Image Canvas.ZIndex="1" Height="80" Width="80" Grid.Row="1" Grid.Column="1" Source="/images/pawn.png" ></Image>
<Image Canvas.ZIndex="1" Height="80" Width="80" Grid.Row="2" Grid.Column="1" Source="/images/pawn.png" ></Image>
<Image Canvas.ZIndex="1" Height="80" Width="80" Grid.Row="3" Grid.Column="1" Source="/images/pawn.png" ></Image>
</Grid>
</Grid>
</Page>
When I try to drag the image over the grid the mouse shows the “Drop Not Allowed” cursor and releasing the image does not fire the Drop event. I asked a teacher about this and she said it was probably because I did not set a background for my grid.
I quickly updated the code, but no luck, the event still did not fire. She didn't really know what was going on and told me to email her if the problem persisted.
I thought I would ask here first.
Thanks in advance for any help.
A quick glance at the MSDN UWP Drag and Drop page suggests that you need to handle the DragOver event, and indicate what drop operations the control will accept (true in any form of XAML and IIRC winforms etc. as well). In UWP, that's the AccepttedOperation property on the event args object (WPF calls that property Effects and it's a different enum type):
private void Grid_DragOver(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Copy;
}

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>

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>

WPF button click event

I am making my first WPF window. I placed a grid onto it and divided the grid into rows and columns that resize automatically if window is resized. There are two buttons that fill two of grid's cells. The buttons contents is set to "OK" and "EXIT" respectively. What I have some difficulty to understand is why would these buttons only work if I click on the text but won't react if I click on the area that is around text and still is inside respective button. Is there a way to make it possibe to click anywhere on the button and it will press down (even if I click somewhere long way from the text)? Any help would be appreciated, thanks!
<Window x:Class="INL.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Please enter your details" Height="350" Width="350" MinWidth="350" MinHeight="350" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" WindowStyle="ToolWindow" Background="White">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Content="Name:"> </Label>
<Label Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Content="Last name:"></Label>
<Label Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="2" Content="ID:"></Label>
<Label Grid.Column="0" Grid.Row="6" Grid.ColumnSpan="2" Content="Result:"></Label>
<TextBox x:Name="TextBoxNamn" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2"></TextBox>
<TextBox x:Name="TextBoxEfternamn" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2"></TextBox>
<TextBox x:Name="TextBoxPersonnummer" Grid.Column="0" Grid.Row="5" Grid.ColumnSpan="2"></TextBox>
<TextBox x:Name="TextBoxResultat" Grid.Column="0" Grid.Row="7" Grid.RowSpan="2" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" IsReadOnly="True" IsReadOnlyCaretVisible="True" />
<Button x:Name="ButtonOK" Grid.Column="1" Grid.Row="7" Content="OK" IsDefault="True" Background="{x:Null}" Click="ButtonOK_Click" ClickMode="Press"></Button>
<Button x:Name="ButtonExit" Grid.Column="1" Grid.Row="8" IsCancel="True" Content="EXIT" Background="{x:Null}" Click="ButtonExit_Click" ClickMode="Press"></Button>
</Grid>
Instead of setting Background to {x:Null}, set it to Transparent.
Setting background to {x:Null} makes surrounding area non-clickable.
Null background does not respond to mouse events.
Refer to this for more details - {x:Null} Vs. Transparent.

UserControl Grid get's displayed with Portrait sizing in Landscape mode

I have this XAML for a UserControl:
<UserControl x:Class="SW.Resources.Controls.HistoryProgressBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Style="{StaticResource AppBackgroundStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="223" />
<ColumnDefinition Width="223" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="TitleText" Style="{StaticResource TitleListItemStyle}" Text="41xxfd" TextWrapping="Wrap" Grid.ColumnSpan="2"/>
<TextBlock x:Name="leftValue" HorizontalAlignment="Right" Style="{StaticResource DetailListItemStyle}" Text="Category: " Grid.Row="1" Grid.Column="0"/>
<TextBlock x:Name="rightValue" Style="{StaticResource DetailListItemValueStyle}" Text="tv" Grid.Row="1" Grid.Column="1" />
<TextBlock x:Name="subLeftValue" HorizontalAlignment="Right" Style="{StaticResource DetailListItemStyle}" Text="Size: " Grid.Row="2" Grid.Column="0" />
<TextBlock x:Name="subRightValue" Style="{StaticResource DetailListItemValueStyle}" Text="400MB" Grid.Row="2" Grid.Column="1" />
<Rectangle Fill="Red" x:Name="progressColor" Grid.RowSpan="4" Grid.Column="2"/>
</Grid>
It looks exactly as I want it to in Portrait. But in landscape, the control ends early. Ideally I would have this control stretch to cover the entire screen. Is this possible to do without having to do any extra code to handle the switch to Landscape?
If you put it inside another grid on the page it should resize to fit the page.
You may want to use percentage based column widths so the columns also resize.
e.g.
<Grid.ColumnDefinitions>
<ColumnDefinition Width="223*" />
<ColumnDefinition Width="223*" />
<ColumnDefinition Width="10*" />
</Grid.ColumnDefinitions>

Categories