C# UWP buttons not align the way I wanted - c#

I have created a button next to my "Start" button. In my xaml page, the button appears at where I want it to be.
However, when I run the app, it appears at a random location.
how do I fix this ?
StackPanel>
<TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
<TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" Text="This page is where your exercise starts " FontSize="20"/>
<TextBlock TextWrapping="Wrap" Margin="0,20,0,0" FontSize="20">
Follow the instruction and press "Start" to begin the exercise.
</TextBlock>
<TextBlock TextWrapping="Wrap" Margin="0,0,0,0" FontSize="15">
(Ensure the connected BLE device is working before starting the exercise.)
</TextBlock>
<TextBlock x:Name="txtClock" TextWrapping="Wrap" Margin="0,10,0,0" FontSize="20"/>
<Button x:Name="btnStart" Content="Start" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,10,0,0" Height="38" Width="106" Click="btnStart_Click_1"/>
<TextBlock x:Name="txtExercise" TextWrapping="Wrap" Margin="0,10,0,0" FontSize="15"/>
<TextBlock x:Name="txtAngle" TextWrapping="Wrap" Margin="0,10,0,0" FontSize="15"/>
<TextBlock x:Name="txtDisplay" TextWrapping="Wrap" Margin="0,10,0,0"/>
<TextBlock x:Name="txtAgain" Text="" TextWrapping="Wrap" Margin="0,10,0,0" FontSize="15"/>
<Button x:Name="btnRefresh" Content="Refresh" HorizontalAlignment="Left" VerticalAlignment="Top" Height="38" Width="106" Margin="150,-158,0,0" Click="btnRefresh_Click"/>

Since you are using the Margin-Property of the button it makes sense that it will pop up somewhere else.
To be honest I don't really know why but I had the same problems.
I would advise you to either use a RelativePanel a StackPanel or a Grid.
You can have a read on this microsoft page. To find out more about the difference between the various types.
A grid would look something like this:
(Keep in mind a grid is 0 indexed)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/> //For a Row of 100 units height
<RowDefinition Height="*"/> //For a Row which fills the rest of the available screen space
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/> //For a column of 100 units width
<ColumnDefinition Width="*"/> //For a column which fills the rest of the screen
</Grid.ColumnDefinitions>
<Button x:Name="Button1" Grid.Row="0" Grid.Column="0" />
<Button x:Name="Button2" Grid.Row="1" Grid.Column="1" />
</Grid>
A Stackpanel would look like this:
(A thing to keep in mind here is that a Stackpanel will not resize its elements when the screen/window size changes)
<Stackpanel Orientation="horizontal">
<Button x:Name="Button1"/>
<Button x:Name="Button2"/>
</Stackpanel>

Related

How to add a separator to the Expander component in UWP app?

I'm looking for a way of implementing this kind of separator to the expander component in UWP app:
Any ideas how to do that?
I've managed to create the similar look of the expander, but I don't know how to implement separators?
Also, I would like to learn how to make expanders kind of "push" other components down when I expand them, so they don't overlap with other components, but simply move them.
Here's the XAML code for this expander:
<muxc:Expander x:Name="FontExpander"
x:Uid="FontExpander"
Width="1155"
IsExpanded="True"
Margin="22,323,0,0"
VerticalAlignment="Top"
Grid.Row="2"
Height="380"
HorizontalContentAlignment="Left"
ExpandDirection="Down">
<muxc:Expander.Header>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<FontIcon Margin="0,0,12,0"
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorPrimaryBrush}"
FontSize="16"
Glyph=""/>
<StackPanel Grid.Column="1"
Margin="0,12"
Orientation="Vertical">
<TextBlock x:Uid="SettingsFontTitle" Style="{StaticResource BodyTextBlockStyle}"/>
<TextBlock x:Uid="SettingsFontDescription"
Style="{StaticResource CaptionTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="WrapWholeWords"/>
</StackPanel>
</Grid>
</muxc:Expander.Header>
<muxc:Expander.Content>
<Grid Margin="-18,-170,-17,-170">
<TextBlock x:Name="SettingsFamily" x:Uid="SettingsFamily" Text="Family" Margin="50,51,1000,286"/>
<ComboBox x:Name="ComboBoxFamily" ItemsSource="{x:Bind Fonts}" Width="200" Margin="950,41,0,0" SelectionChanged="ComboBoxFamily_SelectionChanged" />
<TextBlock x:Name="SettingsStyle" x:Uid="SettingsStyle" Text="Style" Margin="50,106,995,218" Loaded="SettingsStyle_Loaded"/>
<ComboBox x:Name="ComboBoxStyle" Width="200" Margin="950,101,0,0">
<x:String>Regular</x:String>
</ComboBox>
<TextBlock x:Name="SettingsSize" x:Uid="SettingsSize" Text="Size" Margin="50,166,1002,158"/>
<ComboBox x:Name="ComboBoxSize" ItemsSource="{x:Bind FontSizes}" Width="200" Margin="950,161,0,0"/>
<TextBlock x:Name="Text" x:Uid="SettingsText" Text="Hello World! I am so excited to be here!" Margin="62,224,38,126" TextWrapping="Wrap" FontSize="{x:Bind (x:Double)ComboBoxSize.SelectedValue, Mode=OneWay}" TextAlignment="Center"/>
</Grid>
</muxc:Expander.Content>
</muxc:Expander>
Any help would be much appreciated!
A separate can for example be implemented using a Border or a Grid:
<Grid Background="DarkGray" Height="1" />
As a side note, you shouldn't use margins to position your elements. Use an appropriate layout Panel. Using a Grid, you should add ColumnDefinitions and RowDefinitions to it as examplified here.

How to align labels properly in a stack panel

I'm trying to achieve something like this:
As you can see there is a title "This is what I want" that is aligned with
another label
Code that I wrote:
<Grid Width="345" Height="445" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical" Margin="10">
<Label Content="How to align this to the left:" />
<StackPanel Grid.Row="1" Orientation="Horizontal" Background="#D9D9D9">
<Label Content="€" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Label Content="256,00" FontSize="38" FontWeight="Bold" />
</StackPanel>
</StackPanel>
</Grid>
</Grid>
And results of my code looks like this:
As it is possible to notice, label is not aligned to the left, looks like there is some padding or something...
And also € sign is not on a right place, I tried to achieve this like it's on first image, but everything I tried with different types of aligns (horizontal, centered) did not work..
Thanks guys
Cheers
Set the Padding of the Label to 0 or use a TextBlock. A TextBlock is more light-weight than a Label and it has no default Padding.
And you can use the Margin property to move the €-sign up a bit:
<StackPanel Grid.Row="0" Orientation="Vertical" Margin="10">
<TextBlock Text="How to align this to the left:" />
<StackPanel Grid.Row="1" Orientation="Horizontal" Background="#D9D9D9">
<TextBlock Text="€" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Bottom"
Margin="0 0 3 5"/>
<TextBlock Text="256,00" FontSize="38" FontWeight="Bold" />
</StackPanel>
</StackPanel>

How to change GridView.ItemTemplate while app is running?

In my app I have page with GridView and ComboBox. I want to change GridView.ItemTemplate property according to selected item in ComboBox. How should I implement it?
btw, I know about this question, but it is quite old and it does not look like "best practice". (How visibility/invisibility of ui control affects cpu/gpu load?)
My GridView:
<GridView x:Name="gridViewMain" Grid.Row="1" SelectionMode="None" IsItemClickEnabled="True"
ItemsSource="{Binding CurrentList}" ItemTemplate="{StaticResource gridViewMainItemTemplate}"
Loaded="gridViewMain_Loaded" LayoutUpdated="gridViewMain_LayoutUpdated">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ItemClick">
<core:CallMethodAction MethodName="GridViewClick"
TargetObject="{Binding Mode=OneWay}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</GridView>
One of my templates:
<DataTemplate x:Key="gridViewMainItemTemplate">
<Grid x:Name="gridATemplate" Width="185" Height="288">
<Image x:Name="imgATemplate" Source="{Binding image_url}" Stretch="UniformToFill"
HorizontalAlignment="Center" VerticalAlignment="Center" />
<Grid Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlockTitle" Text="{Binding title}"
TextWrapping="Wrap" Style="{StaticResource BodyTextBlockStyle}" Margin="5,0,0,0"
Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Foreground="White" FontWeight="Bold"
MaxHeight="50" />
<TextBlock x:Name="textBlockType" TextWrapping="Wrap" Style="{StaticResource BodyTextBlockStyle}"
Margin="5,0,0,0"
Grid.Column="0" Grid.Row="1" Foreground="White" Text="{Binding type}" FontWeight="Bold" />
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
<TextBlock x:Name="textBlockProgressL" TextWrapping="Wrap"
Style="{StaticResource BodyTextBlockStyle}" FontWeight="Bold" Foreground="White"
Text="Progress:" />
<TextBlock x:Name="textBlockProgressV" TextWrapping="Wrap"
Style="{StaticResource BodyTextBlockStyle}" FontWeight="Bold" Foreground="White"
Text="{Binding watched_episodes}" Margin="10,0,0,10" />
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
Sure you can do this! In XAML you can do anything. What you cannot do is change the Template on the fly without re-rendering. Remember, this is like telling your printer to use card stock. It will obey. If you change the setting to use notebook paper, it will obey that, too. You will just have to print again since it has already printed on card stock.
There are a few ways for you to re-render a GridView. One way is to navigate away from the page and navigate back. That's not ideal sounding in your scenario. Odds are, in your scenario, you just need to reset the ObservableCollection you are using. Like this:
void Reset<T>(ObservableCollection<T> collection)
{
var original = collection.ToArray();
collection.Clear();
foreach (var item in original)
collection.Add(item);
}
Best of luck!
You'll want to use datatemplateselector
http://blogs.msdn.com/b/bryanbolling/archive/2012/12/08/how-to-control-the-datatemplateselector-in-windows-store-apps.aspx
You can create multiple itemtemplates and choose which one to display based on any condition.
You'll have to refresh the gridview whenever the selection changes.

How to Validate 4 Sequential Button Clicks (WPF Application)

What I am having trouble figuring out:
- How to capture 4 button clicks and check if they match the correct sequence similar to entering a 4 digit ATM debit card PIN number
I have a WPF Application and added a new Window that has a PIN pad, numbers 0-9, a question mark button (used as a help button), a backspace button (in case you clicked the wrong number), a TextBox at the top which displays a dot instead of the number (Wingdings - letter 'l'), and a hidden TextBlock which would show an Incorrect PIN message if the numbers were not entered in the correct order. For the time being, I am just going to hard code the 4 digit PIN (7410 for example) since my main goal is learning how to capture and validate the button click sequence. Since I will not be using an Enter key button, I want to continue to the next page as soon as the last number is clicked and the sequence was correct, else display the notification message that the PIN is incorrect. I will also put code in to not allow anything except mouse clicks work and limit the TextBox to only allow a max of 4 digits.
I'm guessing I need a method that is called on each button click which keeps track of the sequence and loops back through each time until all 4 numbers are clicked in the correct sequence then moves on to the next page. Sorry if I'm not explaining well, still learning, so if you need more details I'll do my best to give more.
Thank you in advance.
Below is the xaml code for the PIN pad.
<Border BorderThickness="1" BorderBrush="Black">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Background="Black" Height="50" Grid.ColumnSpan="3" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBlock x:Name="PINTextBlock" Foreground="White" FontSize="18" FontFamily="Wingdings" VerticalAlignment="Center" HorizontalAlignment="Center" MaxWidth="4" />
</Border>
<TextBlock x:Name="ErrorMessageTextBlock" Foreground="Red" Visibility="Collapsed" Grid.ColumnSpan="3" Grid.Row="1" />
<StackPanel Orientation="Horizontal" Grid.Row="2">
<Button x:Name="SevenButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="SevenButton_Click" TabIndex="9">
<TextBlock Text="7" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="EightButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="EightButton_Click" TabIndex="10">
<TextBlock Text="8" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="NineButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="NineButton_Click" TabIndex="11">
<TextBlock Text="9" FontSize="24" FontWeight="Bold" />
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="3">
<Button x:Name="FourButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="FourButton_Click" TabIndex="6">
<TextBlock Text="4" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="FiveButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="FiveButton_Click" TabIndex="7">
<TextBlock Text="5" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="SixButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="SixButton_Click" TabIndex="8">
<TextBlock Text="6" FontSize="24" FontWeight="Bold" />
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="4">
<Button x:Name="OneButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="OneButton_Click" TabIndex="3">
<TextBlock Text="1" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="TwoButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="TwoButton_Click" TabIndex="4">
<TextBlock Text="2" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="ThreeButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="ThreeButton_Click" TabIndex="5">
<TextBlock Text="3" FontSize="24" FontWeight="Bold" />
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="5">
<Button x:Name="QuestionMarkButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="QuestionMarkButton_Click" TabIndex="0">
<TextBlock Text="?" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="ZeroButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="ZeroButton_Click" TabIndex="1">
<TextBlock Text="0" FontSize="24" FontWeight="Bold" />
</Button>
<Button x:Name="BackspaceButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" Height="50" Click="BackspaceButton_Click" TabIndex="2">
<TextBlock Text="Õ" FontFamily="Wingdings" FontSize="24" FontWeight="Bold" />
</Button>
</StackPanel>
</Grid>
</Border>
You can do the validation using Xaml and converters. All you have to do is;
Use binding with ErrorTextBlock and listen for PinTextBlock.Text and run it through converter which will do the actual validation.
This way the validation logic will be seperated nicely and will be reusable. There are other WPF inbuilt validation ways and you can google about them. (IDataErrorInfo and ValidationRules). This would be the "WPF" way.
But the learning curve is little steep. If you just wanna finish this thing, then yes, add this to StackPanel: Button.Click="buttonClickHandler", and in code-behind you will be recieve every button you click in single place. And do your calculations there.
I would have a string that gets appended to (or modified in the case of Backspace or Clear) with each button click, and base my validation off if that string is 4 characters long and equals the PIN #
If it's 4 characters and matches, move to next page. If it's 4 characters and doesn't match, display the error message.
I know this is a learning application, but I'd highly recommend learning the MVVM design pattern if you will be working with WPF.
In that case, I'd have something like a List<KeyValuePair<string, ICommand>> Buttons that gets bound to an ItemsControl with an ItemsPanelTemplate set to a UniformGrid with 3 rows and 3 columns, and the ItemTemplate set to a Button that binds the Content to the Key and the Command to the Value, and an bool IsErrorDisplayed value that gets set to true anytime the error message should be displayed.
<TextBlock x:Name="ErrorMessageTextBlock" Foreground="Red"
Visibility="{Binding IsErrorDisplayed, Converter={StaticResource BooleanToVisibiltyConverter}}"
Grid.ColumnSpan="3" Grid.Row="1" />
<ItemsControl ItemsSource="{Binding Buttons}">
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3" Rows="3" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemTemplate -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="50" Height="50" Command="{Binding Value}">
<TextBlock Text="{Binding Key}" FontSize="24" FontWeight="Bold" />
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I'd also probably do something to secure the PIN # so isn't being stored as plain text.
Associate them all to the same event handler. In that event uselogic to associate the x:Name with an Integer and build up the 4 digit PIN. This just lets you consolidate logic.
private void one_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
Int32 num;
switch (btn.Name)
{
case "one":
num = 1;
break;
case "two":
num = 2;
break;
default:
// problem
}
if (PIN > 1000) // logic
// now you have you have num and can deal with the logic in one click event;
PIN = (PIN * 10) + num;
if (PIN = correctPIN)
{
}
else
{
}
}

How to make Silverlight UserControl fill webpage?

I am building a webapp in Silverlight 4.0 and I would like it to have it expand to fill the width and height of the web browser. However, I can only get it to remain top center at the moment.
I have a Grid with 3 rows, 2 columns and Controls inside these which fill the cells. Therefore I only believe that I need the Grid to stretch to the size of the UserControl and the UserControl to the size of the page. But how should I do this?
Example XAML:
<UserControl x:Class="RepentWeb.MainPage"
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"
xmlns:local="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls.WatermarkedTextBox"
mc:Ignorable="d"
d:DesignHeight="740" d:DesignWidth="1020" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid x:Name="LayoutRoot" Background="White" Width="1020">
<Grid Height="740" HorizontalAlignment="Stretch" Name="grid1" VerticalAlignment="Stretch" Width="1020" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="372*" />
<RowDefinition Height="40*" />
<RowDefinition Height="328" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="415*" />
<ColumnDefinition Width="411*" />
</Grid.ColumnDefinitions>
<local:WatermarkedTextBox Watermark="Source" Margin="12,6,8,8" Name="tbCode" AcceptsReturn="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" FontFamily="Courier New" FontSize="12" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" KeyDown="tbCode_KeyDown" IsTabStop="True" />
<local:WatermarkedTextBox Grid.Column="1" Watermark="Output" AcceptsReturn="True" Margin="9,6,15,8" Name="tbOutput" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch" FontFamily="Courier New" FontSize="12" />
<local:WatermarkedTextBox Grid.Row="1" Grid.Column="1" Watermark="Stack" Grid.RowSpan="2" AcceptsReturn="True" Margin="9,6,15,6" Name="tbStack" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" d:LayoutOverrides="GridBox" VerticalAlignment="Stretch" FontFamily="Courier New" FontSize="12" />
<local:WatermarkedTextBox Grid.Row="2" Grid.Column="0" Watermark="Command line args, one per line. Strings/arrays wrapped in quotes" AcceptsReturn="True" HorizontalScrollBarVisibility="Auto" Margin="12,8,8,6" Name="tbArgs" VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto" FontFamily="Courier New" FontSize="12" />
<Button Grid.Row="1" Grid.Column="0" Content="Run" Height="23" HorizontalAlignment="Left" Margin="12,8,0,0" Name="btnRun" VerticalAlignment="Top" Width="75" Click="btnRun_Click" />
<Button Grid.Row="1" Grid.Column="0" Content="Step Forward" Height="23" HorizontalAlignment="Left" Margin="93,8,0,0" Name="btnStep" VerticalAlignment="Top" Width="115" Click="btnStep_Click" />
<Button Grid.Row="1" Grid.Column="0" Content="Stop" Height="23" HorizontalAlignment="Left" Margin="214,8,0,0" Name="btnStop" VerticalAlignment="Top" Width="75" Click="btnStop_Click" IsEnabled="False" />
<Button Grid.Row="1" Content="Clear All" Height="23" HorizontalAlignment="Right" Margin="0,8,142,0" Name="btnClear" VerticalAlignment="Top" Width="75" Click="btnClear_Click" />
<TextBlock Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="376,0,0,0" Name="lblCurrPos" Text="Current Position:" VerticalAlignment="Top" />
<TextBlock Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="376,17,0,0" Name="lblChar" Text="Char: 0" VerticalAlignment="Top" />
<TextBlock Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="433,17,0,0" Name="lblSymbol" Text="Symbol: " VerticalAlignment="Top" />
</Grid>
</Grid>
</UserControl>
Take 2:
Thanks for the example XAML. Makes it much easier than guessing.
There are a number of changes needed.
First you need to remove the fixed
width and height from your outer
grids as previously mentioned.
Next your left column should be an auto width as the row of buttons determines the width of the left side.
The right column should be simply 1* (or just *) to use up the remaining column space.
The middle row needs to be either auto (to fit the row of buttons) or fixed pixel height. As you have a text box on the right overlapping that row, auto would cause problems if you add a splitter later, so I recommend a fixed pixel height of 40.
The first and last row should both be * in height. They then use 50% of the remaining height.
The buttons should be in a stack panel (as mentioned in the other answer) and the info text in a grid within that stack panel.
If you resize they should change as per the pictures below:
Updated XAML below:
<Grid x:Name="LayoutRoot" Background="White">
<Grid HorizontalAlignment="Stretch" Name="grid1" VerticalAlignment="Stretch" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="0.5*" />
<RowDefinition Height="40" />
<RowDefinition Height="0.5*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="510" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<local:WatermarkedTextBox Watermark="Source" Margin="12,6,8,8" Name="tbCode" AcceptsReturn="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" FontFamily="Courier New" FontSize="12" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" KeyDown="tbCode_KeyDown" IsTabStop="True" />
<TextBox Grid.Column="1" Watermark="Output" AcceptsReturn="True" Margin="9,6,15,8" Name="tbOutput" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch" FontFamily="Courier New" FontSize="12" />
<TextBox Grid.Row="1" Grid.Column="1" Watermark="Stack" Grid.RowSpan="2" AcceptsReturn="True" Margin="9,6,15,6" Name="tbStack" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" d:LayoutOverrides="GridBox" VerticalAlignment="Stretch" FontFamily="Courier New" FontSize="12" />
<TextBox Grid.Row="2" Grid.Column="0" Watermark="Command line args, one per line. Strings/arrays wrapped in quotes" AcceptsReturn="True" HorizontalScrollBarVisibility="Auto" Margin="12,8,8,6" Name="tbArgs" VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto" FontFamily="Courier New" FontSize="12" />
<StackPanel Orientation="Horizontal" Grid.Row="1" d:LayoutOverrides="Width" HorizontalAlignment="Left" Margin="12,0,0,0">
<Button Content="Run" Height="23" Margin="5,0,0,0" x:Name="btnRun" VerticalAlignment="Center" Width="75" Click="btnRun_Click" />
<Button Content="Step Forward" Height="23" Margin="5,0,0,0" x:Name="btnStep" VerticalAlignment="Center" Width="115" Click="btnStep_Click" />
<Button Content="Stop" Height="23" HorizontalAlignment="Left" Margin="5,0,0,0" x:Name="btnStop" VerticalAlignment="Center" Width="75" Click="btnStop_Click" IsEnabled="False" />
<Button Content="Clear All" Height="23" Margin="5,0,0,0" x:Name="btnClear" VerticalAlignment="Center" Width="75" Click="btnClear_Click" />
<Grid Width="107" Margin="13,0,0,0">
<local:WatermarkedTextBox Height="23" HorizontalAlignment="Left" x:Name="lblCurrPos" Text="Current Position:" VerticalAlignment="Top" />
<local:WatermarkedTextBox HorizontalAlignment="Left" Margin="0,17,0,0" x:Name="lblChar" Text="Char: 0" VerticalAlignment="Top" d:LayoutOverrides="HorizontalAlignment" />
<local:WatermarkedTextBox Height="23" HorizontalAlignment="Left" Margin="57,17,0,0" x:Name="lblSymbol" Text="Symbol: " VerticalAlignment="Top" />
</Grid>
</StackPanel>
</Grid>
</Grid>
Take 1:
The overall Silverlight shell size is determined by the settings in your web hosting page and defaults to full browser so the problem is likely your control or more likely the grid within the control.
Make sure you do not have a fixed size specified in either the user-control or the inner grid. Then both default to stretching to the parent.
The exception is if all your columns
are fixed width, then the grid will
collapse back to the total width of
the columns, or if both are "auto" width in
which case the columns will collapse
to the width of the objects within
them (and not force them to stretch).
Make sure at least one of your grid columns is star sized (e.g. 1*) to ensure it takes up the remaining space of the grid. If you want each column to take up 50% of the browser, make them both "1*" width.
If you can post your sample XAML it will be easier to provide an exact fix.
There are a number of things you should consider. #1, remove any fixed width items, such as on the layout grid. (1020)
When you use "*" syntax within row & column definitions with numbers, this is like using a weighting. It isn't like a minimum size or anything like that. Typically this would be for something to use 1/3rd of available width would be to have a two columns with widths of "" (or "1") and "2*" respectively. 2* tells that column to request double the space. (In this case 2/3rds) using heights of 372* and 238* are weighted for available space. If you want controls to have a minimum size then assign the controls MinimumWidth/Height values. (They'll use avaialable space beyond that size as available.)
Generally it's a good idea to use 1 control per cell in a grid. If you want to position more than one control in a cell, then make that another layout control such as a StackPanel or Grid. Stack panels plus left margins work well for arranging things like buttons or text elements. Positioning multiple controls in a layout area using margins is quite messy. If you want controls arranged in multiple rows, or evenly taking up avaiable space, a Grid is preferable.

Categories