Create a full size WPF grid [duplicate] - c#

This question already has answers here:
Autosizing a grid column to take up remaining space in parent
(2 answers)
Closed 7 years ago.
I am trying to fit a wpf grid having 4 cells to be all the time full sized on the screen, having the content of the cells equally split, but i am having problems doing it... This is the code:
<StackPanel x:Name="MainStackPanel" HorizontalAlignment="Center" Orientation="Vertical">
<StackPanel.Resources>
<Style TargetType="Rectangle">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Height" Value="Auto"/>
</Style>
</StackPanel.Resources>
<Grid x:Name="Control1" HorizontalAlignment="Center" Height="150">
<Grid.Resources>
<Style TargetType="Rectangle">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Height" Value="Auto"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Fill="Red" Grid.Row="0" Grid.Column="1"/>
<Rectangle Fill="Blue" Grid.Row="0" Grid.Column="2"/>
<Rectangle Fill="Green" Grid.Row="1" Grid.Column="2"/>
<Rectangle Fill="Yellow" Grid.Row="1" Grid.Column="1"/>
</Grid>
</StackPanel>
Please let me know how should i get this working... or what i am doing wrong...

If you want to have a grid that has four equally spaced cells then you could do something like this.
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
This will create a 2x2 grid that will automatically resize if the screen is resized. In your example, you have your grid inside of a stack panel so it is only going to fill the size of the stack panel. If you want a grid for the entire screen, you need to put your grid as your first container and set its constraints as shown above.

You are using the 'Auto' sizing property. In this case if you want it to be equally split and take up the entire space, you'll want to use '*' for both your row and column definitions. Check out the answer that Samuel gives on this related question.

Related

WPF: How do I get a text box to fill all available horizontal space?

I'm creating a form in WPF. The form has TextBoxes with TextBlocks to their left. A screenshot with GridLines is below:
I want it to look like this (forgive the MS Paint style):
The problem is: the text boxes are really small unless I set the HorizontalAlignment to Stretch, but if I do that, I can't align them to the left. How do I get the Grid containing TextBlock/TextBox to align to the left and make the TextBox fill all available space?
It's trivially easy if I hardcode widths, but that obviously won't work with resizing. I've tried playing with Stack and Dock Panels to hold the Grids with no luck.
I can't use HorizontalAlignment=Stretch, MaxWidth, and Left aligned at the same time? because there is no other control that is the width of the space I am trying to fill.
I also can't use How to get controls in WPF to fill available space? because nothing in my xaml has HorizontalContentAllignment. I tried wrapping stuff in ContentControls and using an ItemsControl to force it with no luck.
The xaml for the form is below. Note, this xaml is for the control that is under the 'Create' header and to the right of the 3 buttons.
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--Left hand side content goes here-->
<DockPanel Grid.Row="0" Grid.Column="1" Grid.RowSpan="2"
Margin="20,0,0,0">
<Grid ShowGridLines="True" DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
<ColumnDefinition SharedSizeGroup="TextBoxColumn"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Input Name:"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBox Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Style="{StaticResource FormTextBox}"
Margin="5,0,5,0"/>
</Grid>
<Grid ShowGridLines="True" DockPanel.Dock="Top" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
<ColumnDefinition SharedSizeGroup="TextBoxColumn"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Input Name:"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBox Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Style="{StaticResource FormTextBox}"
Margin="5,0,5,0"/>
</Grid>
</DockPanel>
</Grid>
The FormTextBox style is:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="TextBox"
x:Key="FormTextBox">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border CornerRadius="10"
Background="{StaticResource InputBrush}">
<Grid>
<Rectangle StrokeThickness="1"/>
<TextBox Margin="1"
Text="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0"
Background="Transparent"
VerticalContentAlignment="Center"
Padding="5"
Foreground="{StaticResource TextBrush}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It rounds the corners, changes the background color, and removes the dotted line that shows up if it was selected before you alt-tabbed out and back into the application.
You indicate that this is the desired layout:
There are a few problems with your current code. First, using a DockPanel to host the TextBlock/TextBox pairs, and second, no control has Grid.IsSharedSizeScope=true set on it. You also have defined a shared size for the text box column when in reality you just want it to take up all the available space.
Here is some code that achieves the desired layout:
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--Left hand side content goes here-->
<StackPanel Orientation="Vertical" Grid.Column="1"
Grid.RowSpan="2"
Margin="20,0,0,0"
Grid.IsSharedSizeScope="True" >
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Grid.Column" Value="0"/>
<Setter Property="Text" Value="Input Name:"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</StackPanel.Resources>
<Border BorderBrush="Blue" BorderThickness="5">
<Grid ShowGridLines="True" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock/>
<TextBox Grid.Column="1"
VerticalAlignment="Center"
Style="{StaticResource FormTextBox}"
Margin="5,0,5,0"/>
</Grid>
</Border>
<Border BorderBrush="Red" BorderThickness="5">
<Grid ShowGridLines="True" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock/>
<TextBox Grid.Column="1"
VerticalAlignment="Center"
Style="{StaticResource FormTextBox}"
Margin="5,0,5,0"/>
</Grid>
</Border>
</StackPanel>
</Grid>
This code produces:
In reality though, if you're going for maximum usability, you'll want to create your own control for the TextBlock/TextBox, and then you could just put it in an ItemsControl of some kind for dynamic content.

XAML Custom control - mathematical fraction

I'm completely new to XAML but not to C# and .NET in general. I'm creating a Windows 8.1 App and I want to create and implement a mathematical fraction control which would represent a structure with numerator and denominator (the first above the second) with horizontal line between them. I'll present here what I already achieved but I know it's very poor and probably the way of my thinking itself is not XAML-like.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestWindowsApplication"
xmlns:local2="using:TestWindowsApplication.CustomControls">
<Style TargetType="local2:MathStructure" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local2:MathStructure">
<StackPanel>
<Border>
<Grid>
<Canvas>
<TextBlock>
1
</TextBlock>
</Canvas>
</Grid>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local2:FractionControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local2:FractionControl">
<Border BorderThickness="2" BorderBrush="Green">
<Grid Height="200" Width="120">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="4" BorderThickness="0,0,0,2" BorderBrush="Red"/>
<Border BorderThickness="1" BorderBrush="White" Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2" Grid.RowSpan="2">
<Grid>
</Grid>
</Border>
<Border BorderThickness="1" BorderBrush="White" Grid.Row="6" Grid.Column="2" Grid.ColumnSpan="2" Grid.RowSpan="2">
<Grid>
</Grid>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I'd like this control to be reusable - I'm going to implement many more of such structures (like integrals, derivatives, sums etc.) so the goal of all of these controls is to enable putting one inside another (e.g. fraction with another fraction as its numerator and an integral as its denominator).
I'm not expecting a working example (although one full example would be great for me to learn), I'll appreciate every tip, hint, code I get here.
I would start off by adding a new UserControl item to your project.
Then, using the standard set of controls (textboxes/blocks, comboboxes, ect)arrange them how you wish to get the desired result you're after.
You can then add styles to those controls - as well as possibly adding in any "background computation" for your fraction-control; such as
1/4 == (value/4)
3/8 == (value/8)*3
If nobody beats me too it, I will attempt to provide you with some code... but I recommend having a quick go yourself :D

Resizeable multiple TextBoxes

I'm going to create some program that resizeable (with drag) multiple Textboxes.
But, I don't know how to build this layout. Is there know how to create drag layout?
It's not entirely clear what your exact specification is here. But the drawing makes it look like you want some cells within the grid to have grab handles for varying width, while others do not. For this purpose, you should be able to use the GridSplitter object.
For example:
<Window x:Class="TestSO36334781GridSplitter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Border BorderBrush="Black" BorderThickness="1">
<Grid>
<Grid.Resources>
<p:Style TargetType="GridSplitter">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Width" Value="5"/>
<Setter Property="Height" Value="10"/>
<Setter Property="Background" Value="Black"/>
<!-- Offset the splitter visually so it's centered over the gridline -->
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="2.5" Y="0"/>
</Setter.Value>
</Setter>
</p:Style>
<p:Style TargetType="TextBox">
<Setter Property="Height" Value="30"/>
</p:Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="Label1" Grid.Column="0"/>
<TextBlock Text="Label1" Grid.Column="1"/>
<TextBlock Text="Label1" Grid.Column="2"/>
<TextBox Grid.Row="1" Grid.Column="0"/>
<TextBox Grid.Row="1" Grid.Column="1"/>
<TextBox Grid.Row="1" Grid.Column="2"/>
<GridSplitter Grid.Row="1" Grid.Column="0"/>
<GridSplitter Grid.Row="1" Grid.Column="1"/>
<TextBox Grid.Row="2" Grid.ColumnSpan="3" Text="A wide textbox here"/>
</Grid>
</Border>
</StackPanel>
</Window>
The above shows a grid with three TextBox controls in the middle row, the widths of which can be modified by the user by dragging the GridSplitter between each of them. The labels above them (i.e. the TextBlock objects) are moved/resized as well, as they share the same column with each respective TextBox.
A fourth TextBox is shown, spanning three columns in the last row, to show how you can still have other grid elements independent of the splitters. I assume you can modify the basic idea to suit your specific needs.
Note that it's important you provide your specific formatting for the splitter objects, and that they appear after the controls they share grid elements with, so that they are above those controls in the z-order.
See also this Stack Overflow question: WPF user controlled grid column width
Addendum:
As hinted at in the (now deleted) comments by Joey, it is possible to place splitter controls without them having to share the cell with (and possibly obscuring) other elements in the grid. The following XAML snippet (i.e. just the Grid element) shows how that would work:
<Grid>
<Grid.Resources>
<p:Style TargetType="GridSplitter">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Width" Value="5"/>
<Setter Property="Height" Value="10"/>
<Setter Property="Background" Value="Black"/>
</p:Style>
<p:Style TargetType="TextBox">
<Setter Property="Height" Value="30"/>
</p:Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="Label1" Grid.Column="0"/>
<TextBlock Text="Label1" Grid.Column="2"/>
<TextBlock Text="Label1" Grid.Column="4"/>
<TextBox Grid.Row="1" Grid.Column="0"/>
<TextBox Grid.Row="1" Grid.Column="2"/>
<TextBox Grid.Row="1" Grid.Column="4"/>
<GridSplitter Grid.Row="1" Grid.Column="1" ResizeBehavior="PreviousAndNext"/>
<GridSplitter Grid.Row="1" Grid.Column="3" ResizeBehavior="PreviousAndNext"/>
<TextBox Grid.Row="2" Grid.ColumnSpan="5" Text="A wide textbox here"/>
</Grid>
The above eliminates the need for the RenderTransform, as each GridSplitter winds up centered in its own column. The ResizeBehavior is set to PreviousAndNext, so that dragging the splitter affects not the width of the column in which the splitter is contained, but instead the widths of the columns immediately before and after it.
It's possible that you could apply a DataGrid control in this scenario and get it to do what you want. But there's nothing in your question that suggests to me you need the full feature set of a DataGrid, or even that you'll be happy with some of the constraints that would involve (such as the way headings are formatted, and whether you can include other fixed-width elements in the layout).

How to set label to multiple line when screen size decrease in wpf

I am creating desktop application using wpf. I have grid in which row is divided in three columns. When the screen size is larger all working well. but when I decrease screen size. label get cropped. I have attached both the scenario
Larger Screen:http://prntscr.com/8kxuas
Small Screen:http://prntscr.com/8kxufe
Here is the code for grid:
<Window x:Class="CharunOptics.Search"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Charun Optics" Height="800px" Width="1600px" WindowStartupLocation="CenterScreen" WindowState="Maximized" Loaded="Window_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="7*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="Search: (Name or Contact)" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" Margin="0,0,25,0" VerticalAlignment="Center" FontSize="20"/>
<TextBox Grid.Column="1" HorizontalAlignment="Stretch" Height="auto" Margin="25,0,25,0" TextWrapping="Wrap" Text="" VerticalAlignment="Center" FontSize="20" Grid.Row="0" Name="TxtName"/>
<Button x:Name="BtnSearch" Grid.Column="2" Grid.Row="0" Content="Search" FontSize="20" Click="BtnSearch_Click" Margin="32"/>
</Grid>
</Grid>
<DataGrid Grid.Row="1" Grid.Column="0" Name="DtGrid" ColumnWidth="*" CanUserAddRows="False">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="{StaticResource PrimaryBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PrimaryFont}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
</Grid>
Is it possible to set label in multiple line when it is overflow just like HTML?
I find the solution for it. I've change the Lable to TextBlock, as lable don't have textwrapping property.
Thanks to #Frisbee for your advise
<TextBlock Text="Search: (Name or Contact)" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" Margin="0,0,25,0" VerticalAlignment="Center" FontSize="20" TextWrapping="Wrap"/>
first:
wpf Label dose not support text wrapping. a better idea is to use text wrapping
a better idea is to use TextBlock which supports text wrapping.
<TextBlock TextWrapping="Wrap">Your huge text here</TextBlock>
You just set the width/ height- property to Auto (it's the default value). That will set the size of the label base of the screen size.

What could be hiding a button in XAML grid? [duplicate]

This question already has answers here:
Back button not working in XAML / W8
(3 answers)
Closed 8 years ago.
I have a button that works in other places within the page. If I add it to a particular grid though, it gets displayed but it's not clickable. Here's my full markup for that:
<Grid Style="{StaticResource NogMasterPageGridStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Page title -->
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="15"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="100"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
// THIS BUTTON SHOULD BE CLICKABLE, AND IS ELSEWHERE
<Button IsHitTestVisible="True" Grid.Column="0" Grid.Row="1" Canvas.ZIndex="9999" Content="Go Back" Style="{StaticResource NogButton}"
Click="Click_GoBack"/>
<StackPanel Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Orientation="Vertical" Margin="40,0,0,0">
<Image Style="{StaticResource NogLogoImage}" VerticalAlignment="Center"></Image>
<TextBlock Text="NOG" Style="{StaticResource NogPageTitle}"
IsHitTestVisible="false" TextWrapping="NoWrap" Margin="2,-35,0,0" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
What could be causing the button to not be clickable in this particular grid?
Edit: I tried disabling the style of the grid and that didn't work. Here it is just in case:
<Style x:Key="NogButton"
TargetType="Button">
<Setter Property="Foreground" Value="{StaticResource ColorBrushWhite}"/>
<Setter Property="Background" Value="{StaticResource ColorBrushGreen}"/>
<Setter Property="FontSize" Value="18"/>
</Style>
<ImageBrush x:Key="BackgroundNog"
ImageSource="ms-appx:///Assets/WhiteBackgroundAndPen.jpg"
Stretch="UniformToFill" />
<Style x:Key="NogMasterPageGridStyle"
BasedOn="{StaticResource LayoutRootStyle}"
TargetType="Panel">
<Setter Property="Background" Value="{StaticResource BackgroundNog}" />
</Style>
I propose you to solve this issue by using Snoop, it is a wonderful application that lets you view all the layers of you wpf app, and also view the data contexts and you can change the properties values. Hope it helps
Have you set IsHitTestVisible to False on some ancestor in the parent chain of the Button? That could be the reason.
From the MSDN:
... if an element is a child element of an element that is not hit test visible, the effective value of the property on the child will remain false, even if attempting to set that value locally.

Categories