Homunculus Reticulli
Homunculus Reticulli

Reputation: 68426

WPF form XAML : How to correctly position these controls (and get the button to behave normally when clicked)

So, I am new to WPF. Actually, this is my first WPF project. I come from a unix desktop (and Web) programming background, so I'm not new to programming or mark up languages.

Q1: First, My application is a simple dialog that cannot be min/maximized or resized (for simplicity), so I don't mind fixing (ie. hardcoding) my layout.

Using HTML to explain, this is what I want my "form" to look like:

<div>
    <div>
        <span>This is my Left Adjusted Title</span>
        <span>Some Right Adjusted Stuff</span>
    </div>
    <div>
        <div>
             <div>This is the parent container</div>
             <div>
                  <div>Title for option 1</div>
                  <div>
                       Radio Button for option 1
                  </div>

                  <div>Title for option 2</div>
                  <div>
                       Radio Buttons for option 2
                  </div>
              </div>
        </div>
        <div>
             <span>Right Floated Button</span>
        </div>
        <hr />
        <div>
            <div>These are the Results</div>
            <textarea>
                Vertically scrollable text here (nice if can be color formatted with underlines etc) ...
            </textarea>
        </div>
        <div id="footer">
            <div><a href='http://www.google.com'>Click here</a></div>
        </div>
    </div>
</div>

This, on the other hand, is my XAML (which I have kludged together from the Visual Designer):

<Window x:Name="wndMain" x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ews="clr-namespace:ExtraWindowStyles"
        ResizeMode="NoResize"
        ews:ExtraWindowStyles.CanMinimize="false" 
        ews:ExtraWindowStyles.CanMaximize="false"         
        Title="Hello World" Height="501.492" Width="842.285">
    <Grid>
        <GroupBox Header="Input Parameters" HorizontalAlignment="Left" Height="173" Margin="10,25,0,0" VerticalAlignment="Top" Width="801" >
            <StackPanel Orientation="Horizontal" Margin="0,0,96,0">
                <StackPanel Margin="10">
                    <Label FontWeight="Bold">First Group</Label>
                    <RadioButton x:Name="opt11">Option 1 - 1</RadioButton>
                    <RadioButton x:Name="opt12">Option 1 - 2</RadioButton>
                    <RadioButton x:Name="opt13">Option 1 - 3</RadioButton>
                </StackPanel>
                <StackPanel Margin="10">
                    <Label FontWeight="Bold" Content="Second Group"/>
                    <RadioButton x:Name="opt21" Content="Option 2 - 1"/>
                    <RadioButton x:Name="opt22" Content="Option 2 - 2"/>
                    <RadioButton x:Name="opt23" Content="Option 2 - 3"/>
                </StackPanel>
            </StackPanel>

        </GroupBox>
        <Separator HorizontalAlignment="Left" Height="80" Margin="17,203,0,0" VerticalAlignment="Top" Width="794"/>
        <Button x:Name="btnSubmit" Content="Explore" HorizontalAlignment="Left" Height="34" Margin="632,203,0,0" VerticalAlignment="Top" Width="179" Click="btnSubmit_Click"  />
        <Label Content="Results:" HorizontalAlignment="Left" Height="28" Margin="10,242,0,0" VerticalAlignment="Top" Width="161"/>
        <Label Content="My App" HorizontalAlignment="Left" Height="23" Margin="696,439,0,0" VerticalAlignment="Top" Width="130" FontSize="9"/>
        <TextBlock>           
            <Hyperlink NavigateUri="http://www.google.com" RequestNavigate="Hyperlink_RequestNavigate">
                Click Here
            </Hyperlink>
        </TextBlock>
        <Rectangle Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="162" Margin="17,270,0,0" Stroke="Black" VerticalAlignment="Top" Width="794"/>
        <Label x:Name="lblResult" Content="" HorizontalAlignment="Left" Height="157" Margin="17,275,0,0" VerticalAlignment="Top" Width="794"/>
    </Grid>
</Window>

How do I fix this XAML so it is rendered the way I showed in the HTML snippet?

Q2: Why does the WPF rendered button not behave like a button?. This is really wierd, it does not depress when clicked, how do I get the 'normal' button click behaviour ?

Upvotes: 1

Views: 1818

Answers (1)

Mike Guthrie
Mike Guthrie

Reputation: 4059

I've (mostly) updated your XAML, attached below, to get you started in the right direction. Of note, pay attention, as Bradley Uffner mentioned, to how elements are arranged within the Grid via RowDefinitions and the Grid.Row attached property.

Further, as you progress in WPF, look into MVVM pattern, as it creates much cleaner and more logic code, being much easier to maintain. To this end, you'll want to start familiarizing yourself on the Binding expressions in WPF, such as can be found at A Data Binding Primer.

I've left most of your static Height definitions in place, but you can also allow these controls to fit dynamically via any combination of Height on RowDefinition, Width on ColumnDefinition, and the HorizontalAlignment and VerticalAlignment of the controls themselves.

<Window x:Name="wndMain" x:Class="MyApp.MainWindow"
        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:WpfControlPositioning"
        mc:Ignorable="d"
        ResizeMode="NoResize"
        Title="Hello World" Height="501.492" Width="842.285"
        WindowStyle="ToolWindow">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <GroupBox Grid.Row="0" Header="Input Parameters" Height="173" Margin="10">
            <StackPanel Orientation="Horizontal">
                <StackPanel Margin="10">
                    <Label FontWeight="Bold">First Group</Label>
                    <RadioButton x:Name="opt11">Option 1 - 1</RadioButton>
                    <RadioButton x:Name="opt12">Option 1 - 2</RadioButton>
                    <RadioButton x:Name="opt13">Option 1 - 3</RadioButton>
                </StackPanel>
                <StackPanel Margin="10">
                    <Label FontWeight="Bold" Content="Second Group"/>
                    <RadioButton x:Name="opt21" Content="Option 2 - 1"/>
                    <RadioButton x:Name="opt22" Content="Option 2 - 2"/>
                    <RadioButton x:Name="opt23" Content="Option 2 - 3"/>
                </StackPanel>
            </StackPanel>
        </GroupBox>

        <Separator Grid.Row="1" Height="3" Margin="10,0"/>

        <Button Grid.Row="2" x:Name="btnSubmit" Content="Explore" HorizontalAlignment="Right" Height="34" Margin="10" Width="179" Click="btnExplore_Click"  />

        <Label Grid.Row="3" Content="Results:" HorizontalAlignment="Left" Margin="10,0"/>

        <!-- I don't know what to make of this, so I've left it commented out.
                <TextBlock>
                    <Hyperlink NavigateUri="http://www.google.com" RequestNavigate="Hyperlink_RequestNavigate">
                        Click Here
                    </Hyperlink>
                </TextBlock>
                -->

        <!-- Note that I've substituted a ReadOnly TextBox in place of the Rectangle + Label here.  The TextBox supplies
                     the bordered look of the rectangle, but has the different behavior of allowing text selection from within
                     the control, such as for copying your Results to paste elsewhere. -->
        <TextBox Grid.Row="4" x:Name="lblResult" Margin="10,0" IsReadOnly="True" Background="#FFF4F4F5" BorderBrush="Black"/>

        <Label Grid.Row="5" Content="My App" HorizontalAlignment="Right" Height="23" Margin="0" FontSize="9"/>
    </Grid>
</Window>

EDIT: I forgot to point out that, since you were arranging everything via Margin and had some odd sizes and layouts of some elements (i.e., the "Click Here" link) that the reason your Button didn't behave as expected is because it had other controls overlaying the top of it.

Upvotes: 2

Related Questions