Button not filling grid cell - silverlight

I'm trying to build a simple 3x3 grid in Silverlight with a button in each grid cell. The grid definition is below. When I add button to the grid they never fill the 130x130 grid cell. I set the margin and padding to 0 on the buttons as well as setting their horizontal and vertical alignment to Stretch.
<Grid x:Name="Test" ShowGridLines="True" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="130"></RowDefinition>
<RowDefinition Height="130"></RowDefinition>
<RowDefinition Height="130"></RowDefinition>
<RowDefinition Height="130"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130"></ColumnDefinition>
<ColumnDefinition Width="130"></ColumnDefinition>
<ColumnDefinition Width="130"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Style x:Key="OperandButton" TargetType="Button">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Background" Value="{StaticResource PhoneAccentColor}" />
<Setter Property="FontSize" Value="50" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
</Style>
<Button Content="10" Style="{StaticResource OperandButton}" Grid.Row="0" Grid.Column="0" />
<Button Content="3" Style="{StaticResource OperandButton}" Grid.Row="0" Grid.Column="1" />
<Button Content="7" Style="{StaticResource OperandButton}" Grid.Row="0" Grid.Column="2" />

Your code should just work fine. Just try this code as it is.
<Grid x:Name="Test" ShowGridLines="True" HorizontalAlignment="Center" >
<Grid.Resources>
<Style x:Key="OperandButton" TargetType="Button">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Background" Value="Blue" />
<Setter Property="FontSize" Value="50" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="130"></RowDefinition>
<RowDefinition Height="130"></RowDefinition>
<RowDefinition Height="130"></RowDefinition>
<RowDefinition Height="130"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="130"></ColumnDefinition>
<ColumnDefinition Width="130"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Content="10" Style="{StaticResource OperandButton}" Grid.Row="0" Grid.Column="0" />
<Button Content="3" Style="{StaticResource OperandButton}" Grid.Row="0" Grid.Column="1" />
<Button Content="7" Style="{StaticResource OperandButton}" Grid.Row="0" Grid.Column="2" />
</Grid>
Let me know if you still not getting it.

Try the following,
When you open your project in Blend. Right click the button, go to edit template, edit current. You'l find that every button has a grid and a container. Make the size of both equal then, you'l see the default border's size same as the buttons size.
The same template can be used for other buttons too.
Now try enveloping the buttons in the grid.

Looking at the template in blend solved the problem. The following property was set on the Border:
Margin="{StaticResource PhoneTouchTargetOverhang}"
Once this was set to 0, the grid was perfect. Thanks for the guidance.

Try this, it's must not specified VerticalAlignment Or HorizontalAlignment.
Margin="-10"

Related

What is the best way to set a distance between Grid's or StackPanel's elements in XAML?

I have a Grid with some elements inside:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="SomeText" Grid.Column="0" Grid.Row="0" />
<TextBox Grid.Column="1" Grid.Row="0" />
<TextBlock Text="SomeText" Grid.Column="0" Grid.Row="1" />
<TextBox Grid.Column="1" Grid.Row="1" />
<TextBlock Text="SomeText" Grid.Column="0" Grid.Row="2" />
<TextBox Grid.Column="1" Grid.Row="2" />
</Grid>
The problem is that it looks tightly:
what i have
Margin property solves this problem, but I should to set this property to each element inside a grid. It is a hard way.
I want to obtain something like this setting margin property only once, but not for each element:
what i want to obtain
You can put the Margin into an implicit Style in the Grid.Resources.
e.g.
<Style x:Key="MarginStyle" TargetType="FrameworkElement">
<Setter Property="Margin" Value="5"/>
</Style>
<Style TargetType="TextBox" BasedOn="{StaticResource MarginStyle}"/>
<Style TargetType="TextBlock" BasedOn="{StaticResource MarginStyle}"/>
You can also use an ItemsControl to apply a common style.
e.g.
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- Panel without children here -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="FrameworkElement">
<Setter Property="Margin" Value="5"/>
</Style>
</ItemsControl.ItemContainerStyle>
<!-- Children here -->
<Label Grid.Row="0" Content="Field 1: "/>
<Label Grid.Row="1" Content="Field 2: "/>
<TextBox Grid.Column="1" Grid.Row="0"/>
<TextBox Grid.Column="1" Grid.Row="1"/>
</ItemsControl>
Why not make a style and apply it to the elements?
You can add something like this to the resources section of your grid
<Grid.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="0,5" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="0,5" />
</Style>
</Grid.Resources>
Alternatively, you could also use a vertical stackpanel populated with 2 column grids.
Then just style the grids

WPF Button Style Doesn't Show Text

I'm new to this so please bear with me.
I now have this Style. Paste this into a window to see it in action.
<Window.Resources>
<Style x:Key="SelectionButton3"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ClipToBounds="False">
<Grid.RowDefinitions>
<RowDefinition Height="75" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="55" />
</Grid.ColumnDefinitions>
<Border x:Name="TheBorder"
BorderThickness="0,1.5,1.5,1.5"
CornerRadius="3"
Background="SteelBlue"
Height="35"
Grid.Column="1"
Grid.Row="0"
Margin="-31"
BorderBrush="DarkSlateBlue"/>
<Rectangle Name="TheRectangle"
Fill="SteelBlue"
Stroke="DarkSlateBlue"
Grid.Row="0"
Grid.Column="0">
<Rectangle.LayoutTransform>
<RotateTransform Angle="-45" />
</Rectangle.LayoutTransform>
<Rectangle.BitmapEffect>
<DropShadowBitmapEffect ShadowDepth="5" />
</Rectangle.BitmapEffect>
</Rectangle>
<ContentPresenter x:Name="ContentArea"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="TheBorder"
Property="BitmapEffect">
<Setter.Value>
<DropShadowBitmapEffect ShadowDepth="0" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground"
Value="White"/>
<Setter Property="FontFamily"
Value="Segoe UI" />
<Setter Property="FontSize"
Value="20" />
</Style>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="250" />
</Grid.ColumnDefinitions>
<Button Grid.Row="1"
Grid.Column="1"
Style="{StaticResource SelectionButton3}"
Margin="0,0,0,5"
Click="Button_Click">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Height="35"
Width="35"
Stretch="Fill"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="0"
Margin="32.5,0,0,0"
Source="/app;component/Media/Images/Mail/email.png" />
<TextBlock Text="Email"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="22,0,0,0"/>
</Grid>
</Button>
I have 2 questions:
1) Why is only part of the text showing up?
2) How do I put the Image and TextBlock in the Template and just bind to them?
The reason why your Text is clipped is because you did not specify Grid.Row and Grid.Column for your ContentPresenter. This causes your button's content to default to the 0th Row and 0th Column on your ControlTemplate, which in combination with your margins and positions causes the Textblock on your Button Element to be cut off. I am guessing this might be your intent?
<ContentPresenter x:Name="ContentArea"
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Content="{Binding Path=Content,
RelativeSource={RelativeSourceTemplatedParent}}" />
Now the ContentPresenter will span both columns on the ControlTemplate's Grid, so your Textblock will have more room to display itself.
To answer your second question How do I put the Image and Textblock in the template and just bind to them?
One way to do it is to subclass the Button class, call it MyImageButton for example, and implement two new Dependency Properties called Image and Text in this new class. Then you can move your <Image> and <TextBlock> into your Control Template and bind them to your new Image and Text Properties. You can then instantiate MyImageButton and used the new Properties to set the button's image and text.

WPF styles and grid layout issues

RESOLVED EDIT:
Because it is not clear through the discussion nothing was really wrong with the structure of the grids or their placement. The designer however misrepresented where the grid was. For some reason it placed the grid in the upper left hand corner of the window rather then within the content portion of the window. Once that is accounted for everything else lined up as anticipated.
I am working on a WPF project and have run into an issue with styling my forms. I needed a custom window, one without all the windows stuff; so I created a custom window style that I could apply to all my windows. Within that style I created a grid so that I could more easily place the default elements of the default window style. Then on my dashboard window I apply the default window style and all looks well. But once I attempt to place a grid within the dashboard window things start getting wonky.
In order to compensate for this I added an Adorner Decorator to the grid in the default style and placed it at the content location of that grid. This does allow me to place my content within dashboard window, but it does not follow the grid rules made by the dashboards grid.
So all I am attempting to do is create a custom window style that can be applied to all of my windows, and be able to use a grid to slice up the area designated contented by that windows default style.
This is the meaningful portion of the windows style, it lays out a grid for the boarders(drag labels), header, footer, control bar buttons(max, min, close) and content.
<Style x:Key="DefaultWindowStyle" TargetType="{x:Type Window}" >
<Setter Property="Margin" Value="5" />
<Setter Property="ResizeMode" Value="NoResize" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Background" Value="MidnightBlue" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid Name="WindowGrid">
<Grid.RowDefinitions>
<RowDefinition Name="TopBorderRow" Height="5" />
<RowDefinition Name="TitleBarRow" Height="30" />
<RowDefinition Name="RContentRow" Height="*" />
<RowDefinition Name="BottomBorderRow" Height="5" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Name="LeftBorderCol" Width="5" />
<ColumnDefinition Name="CContentCol" Width="*" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
<ColumnDefinition Name="RightBorderCol" Width="5" />
</Grid.ColumnDefinitions>
<s:ResizeThumb Style="{StaticResource ThumbAsBorderStyle}" Height="5" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6" Cursor="SizeNS" HorizontalAlignment="Stretch" VerticalAlignment="Top" />
<s:ResizeThumb Style="{StaticResource ThumbAsBorderStyle}" Height="5" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="6" Cursor="SizeNS" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" />
<s:ResizeThumb Style="{StaticResource ThumbAsBorderStyle}" Width="5" Grid.Row="0" Grid.Column="0" Grid.RowSpan="4" Cursor="SizeWE" HorizontalAlignment="Left" VerticalAlignment="Stretch" />
<s:ResizeThumb Style="{StaticResource ThumbAsBorderStyle}" Width="5" Grid.Row="0" Grid.Column="5" Grid.RowSpan="4" Cursor="SizeWE" HorizontalAlignment="Right" VerticalAlignment="Stretch" />
<s:ResizeThumb Style="{StaticResource ThumbAsBorderStyle}" Height="5" Width="5" Grid.Row="0" Grid.Column="0" Cursor="SizeNWSE" HorizontalAlignment="Left" VerticalAlignment="Top" />
<s:ResizeThumb Style="{StaticResource ThumbAsBorderStyle}" Height="5" Width="5" Grid.Row="0" Grid.Column="5" Cursor="SizeNESW" HorizontalAlignment="Right" VerticalAlignment="Top" />
<s:ResizeThumb Style="{StaticResource ThumbAsBorderStyle}" Height="5" Width="5" Grid.Row="3" Grid.Column="0" Cursor="SizeNESW" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
<s:ResizeThumb Style="{StaticResource ThumbAsBorderStyle}" Height="5" Width="5" Grid.Row="3" Grid.Column="5" Cursor="SizeNWSE" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
<s:DragLabel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="6" Style="{DynamicResource DefaultWindowTitle}" Content="{TemplateBinding Title}"/>
<s:TitleBarButton x:Name="Minimize" Style="{StaticResource TitleBarButton}" Grid.Row="1" Grid.Column="2">
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{DynamicResource ButtonMinimize}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="{DynamicResource ButtonMinimizeHover}"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</s:TitleBarButton>
<s:TitleBarButton x:Name="Maximize" Style="{StaticResource TitleBarButton}" Grid.Row="1" Grid.Column="3">
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{DynamicResource ButtonMaximize}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="{DynamicResource ButtonMaximizeHover}"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</s:TitleBarButton>
<s:TitleBarButton x:Name="Close" Style="{StaticResource TitleBarButton}" Grid.Row="1" Grid.Column="4">
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{DynamicResource ButtonClose}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="{DynamicResource ButtonCloseHover}"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</s:TitleBarButton>
<AdornerDecorator Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="4">
<ContentPresenter />
</AdornerDecorator>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here is the code of the dashboard window where I am attempting to place fitted elements in their correct grid slots (those created by the dashboard window). The grid created blow looks as though all of the rows and columns are in the right spot, and their elements should simply fit, but they have strange margins. So the StudySessionPanel(which is 128x234) should fit perfectly within row 1, col 2, but as you can see it require colsaps, margins and other junk in order to place it at the correct location.
Title="Dashboard"
Style="{DynamicResource DefaultWindowStyle}" mc:Ignorable="d"
Height="840" Width="1024">
<Grid Name="DashboardGrid" Width="1024" Height="840">
<Grid.RowDefinitions>
<RowDefinition Height="63" />
<RowDefinition Height="128" />
<RowDefinition Height="234" />
<RowDefinition Height="18"/>
<RowDefinition Height="380" />
<RowDefinition Height="16" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16" />
<ColumnDefinition Width="15.25" />
<ColumnDefinition Width="234" />
<ColumnDefinition Width="15.25" />
<ColumnDefinition Width="280" />
<ColumnDefinition Width="15.25" />
<ColumnDefinition Width="417" />
<ColumnDefinition Width="15.25" />
<ColumnDefinition Width="16" />
</Grid.ColumnDefinitions>
<cc:PanelStudySession x:Name="StudySessionPanel" Grid.ColumnSpan="3" Margin="15,66,16,62" Grid.RowSpan="2" Grid.Row="1">
</cc:PanelStudySession>
<cc:PanelPerformance x:Name="PerformancePanel" Grid.Column="3" Grid.ColumnSpan="4" Margin="0,66,10,62" Grid.Row="1" Grid.RowSpan="2">
</cc:PanelPerformance>
<cc:PanelProgress x:Name="ProgressPanel" Grid.Column="1" Grid.ColumnSpan="4" Margin="0,190,10,62" Grid.Row="2" Grid.RowSpan="3">
</cc:PanelProgress>
<cc:PanelHistory x:Name="HistoryPanel" Grid.Column="5" Grid.ColumnSpan="2" Margin="0,190,15,62" Grid.Row="2" Grid.RowSpan="3">
</cc:PanelHistory>
</Grid>
This is the image with the margins, and row/col spans
Ignoring the designer the elements sort of line up, though some of them get chopped. It looks the same when ran as it does in the presenter.
Your StudySessionPanel is actually being put in rows 1-2 (Row=1, RowSpan=2) and columns 0-2 (no column and ColumnSpan=3). Just set Grid.Row and Grid.Column if you want to put it in a cell.

How to make Border controls to have the same width inside a single Grid control?

I have something like this:
<MyView>
<Style TargetType="Border" x:Key="Module">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Gray" />
<Setter Property="Padding" Value="10" />
<Setter Property="Margin" Value="10" />
</Style>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Name="Border1" Style="{StaticResource Module}">
<!--some controls with non-fixed width-->
</Border>
<Border Grid.Row="1" Name="Border2" Style="{StaticResource Module}">
<!--some controls with non-fixed width-->
</Border>
<Border Grid.Column="1" Grid.RowSpan="2" Style="{StaticResource Module}" Name="Border3">
<!--some controls with non-fixed width-->
</Border>
</Grid>
</MyView>
The controls inside Border1 and Border2 might have different width, so their borders will also have different width, which doesn't look good. How do I force Border1 and Border2 border to have same width so it would look better?
The solution of setting same width manually doesn't count because the width of child controls of Border1 and Border2 may vary.
And the content of Border3 just eats up all available space, and this is fine.
Add <Setter Property="HorizontalAlignment" Value="Stretch" /> to your Border Style

Expanders in distinct columns in one row. Expand to the full row

I have two expanders in one grid row but in distinct columns. How can I expand each of it to the full row but not on column only.
<Grid x:Name="mainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90"/>
<ColumnDefinition Width="90"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MinHeight="40" />
<RowDefinition MinHeight="40" />
</Grid.RowDefinitions>
<Controls:Expander Grid.Row="0" Grid.Column="0" x:Name="expander2" Header="Header1"
MinHeight="33" Padding="3">
<TextBlock Text="SomeText1" />
</Controls:Expander>
<Controls:Expander Grid.Row="0" Grid.Column="1" x:Name="expander1" Header="Header2"
MinHeight="33" Padding="3">
<TextBlock Text="SomeText2" />
</Controls:Expander>
</Grid>
expander1 and expander2 should expand to the whole row 0.
Introduce the triggers for Expanders that check their IsExpanded property and set their Grid.RowSpan as 2.
<Style TargetType="{x:Type Expander}">
<Style.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter Property="Grid.RowSpan" Value="2" />
</Trigger>
</Style.Triggers>
</Style>
For silverlight
<Style TargetType="{x:Type Expander}">
<Setter Property="Grid.RowSpan"
Value="{Binding IsExpanded,
RelativeSource={RelativeSource
Self},
Converter={StaticResource
local:ExpansionToRowSpanConverter}}"
</Style>
Code behind ... (this is just for illustration)
ExpansionToRowSpanConverter.Convert(....)
{
return (bool)value ? 2 : 1;
}
Does this work for you?

Resources