I am working on a WPF application. I have a StackPanel in my xaml file. In StackPanel there are three buttons. Problem is that all button are either on left side or on the right side. What I want is that one button is one the left side and two buttons on the right side.
<StackPanel Orientation="Horizontal" FlowDirection="RightToLeft" >
<Button Content="Open"/>
<Button Content="Close"/>
<Button Content="Help"/>
</StackPanel>
The output of this is like this.
As you can see that there is a lot of space on the left side. I want my Help button to the extreme left side whil Close and Open on the extreme right. I think I can do this by implementing a grid or something like that, but I want to ask that whether I can do this with using stack panel only.
You cannot do that with a StackPanel, however you don't "have" to use a Grid.
You can use a DockPanel as a compromise
<DockPanel LastChildFill="False">
<Button Content="Help" DockPanel.Dock="Left" />
<Button Content="Close" DockPanel.Dock="Right" />
<Button Content="Open" DockPanel.Dock="Right" />
</DockPanel>
LastChildFill="False" will make sure your last added control does not end up "filling" up all the remaining space thereby giving you the look you want.
You need to use a Grid for that:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="Help"/>
<Button Grid.Column="1" Content="Close"/>
<Button Grid.Column="2" Content="Open"/>
</Grid>
Related
I have a custom control ButtonRow which will end up going into a different control.
It is very simple, it has one Border, on label and one button.
I need to make it so that the border will extend its width to fill up to where the button is.
This is not happening as you can see in the below image:
The XAML can be found below. I have tried fiddling about with the horizontal alignment of both he label and the border, but they will only ever re-size to fit the text content of the label.
I know there are existing question with very similar problems and names, but none have needed to do quite the same thing or have helped me solve my problem.
I have tried using a StackPanel in horizontal alignment but all it did was make the button go next to the border.
How can I make the border expand to fill the available space?
<Grid>
<DockPanel Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="dockPanel1" VerticalAlignment="Top" Width="Auto">
<Border BorderBrush="#FFDADFE1" Background="#FFECF0F1" BorderThickness="1" Height="20" Name="bdrFilter" HorizontalAlignment="Stretch">
<Label Content="Filter..." FontStyle="Italic" Foreground="#FF6C7A89" Height="20" Name="lblFilter" Padding="5,0" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" />
</Border>
<Button Style="{StaticResource FlatButtonStyle}" Content="+" Height="20" HorizontalAlignment="Right" Name="btnAddFilter" VerticalAlignment="Top" Width="20" Foreground="#FF6C7A89" ForceCursor="True" BorderBrush="{x:Null}" />
</DockPanel>
</Grid>
(The button style does not affect its alignment or any other relevant properties)
A DockPanel is not the correct Panel to use for this requirement... like a StackPanel, it does not resize its contents. Instead, just use a regular Grid (which also uses less resources than a DockPanel):
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border BorderBrush="#FFDADFE1" Background="#FFECF0F1" BorderThickness="1"
Height="20" Name="bdrFilter" VerticalAlignment="Top">
<Label Content="Filter..." FontStyle="Italic" Foreground="#FF6C7A89"
Height="20" Name="lblFilter" Padding="5,0" />
</Border>
<Button Grid.Column="1" Content="+" Height="20" HorizontalAlignment="Right"
Name="btnAddFilter" VerticalAlignment="Top" Width="20" Foreground="#FF6C7A89"
ForceCursor="True" BorderBrush="{x:Null}" />
</Grid>
Please see the Panels Overview page on MSDN for more information about the different Panels in WPF.
This might help you out. Setting LastChildFill=True inside a DockPanel does exactly what the name suggests.
Working on the XAML file and C# at the back end.
I have totally 4 buttons.
By clicking 1st, other three will be Visible and by clicking same 1st button the three will hide.
Though they are working fine, I want them to aligned vertical and not horizontal by breaking the line.
Also I need to add images before each buttons. Something like this.
Please suggest. Thank you.
Followed this answer, but I understand its for the text and not for buttons.
Here's by code for the buttons:
<Button Content ="Buttons" Click="ButtonBase_OnClick" Margin="15,15,15,15"></Button>
<Button Content="Topo Map" Visibility="Collapsed" Click="Topo_OnClick"
Name="But2" Margin="15,15,15,15"/>
<Button Content="Street Map" Visibility="Collapsed" Click="Street_OnClick"
Name="But3" Margin="15,15,15,15"/>
<Button Content="Imagery Map" Visibility="Collapsed"Click="Imagery_OnClick"
Name="But4" Margin="15,15,15,15"/>
You will need to wrap your buttons in a content container, like a stackpanel or grid. Keep in mind a stack panel will size to fit it's contents where a grid can size to fit available space. I would use a stackpanel to hold the buttons and a grid to hold your button content:
<StackPanel Orientation="Vertical">
<Button Click="ButtonBase_OnClick" Margin="15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image />
<TextBlock Text="Buttons" />
</Grid>
</Button>
...
</StackPanel>
I think you're looking for the WrapPanel of the Silverlight Toolkit.
I'm building a window for a kiosk application that has an admin screen to connect to a wifi network. Actually, I'm porting an existing WinForms app that already does this, but doesn't give us the flexibility we want to create a more interesting UI. So, we're moving to WPF.
The window is pretty straightforward, it has a listview to show networks that it finds, and if you click on one, it will connect to it. In order to connect, we need to prompt for the security code for that network if it needs one. To do this, we open a popup that has three sections - a "dialog-y" prompt section at the top, a spacer row, and a blank border that will sit behind an onscreen keyboard, but have nice rounded corners.
That top section has a header, a text box, and two buttons, connect and cancel. Again, nothing complex.
All this works. You click a network, we show the popup and the keyboard, except: the textbox for the passcode never gets the focus. Even if you click on it. No focus. The only trick I've found to get it to focus is to click off the popup (like back on the listview, which is already ignoring clicks if the popup is open, so it's safe), then click back on the textbox, and voila! focus. I really don't think I want to put that in a user manual though.
Here's the popup portion of the xaml:
<Popup x:Name="popPasscode" Placement="Top" HorizontalOffset="50" VerticalOffset="1000" AllowsTransparency="True" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="50" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="White" CornerRadius="20" Width="600" Height="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="#464646" Height="50" Margin="8,10,8,0" CornerRadius="25" >
<Label x:Name="lblTitleSecurityCode" Content="Enter the security code" Foreground="White" FontFamily="Arial" FontSize="30" FontWeight="Bold" HorizontalAlignment="Center"/>
</Border>
<TextBox Grid.Row="1" x:Name="tbPasscode" Height="50" FontFamily="Arial" FontSize="30" Margin="40,0,40,0"/>
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="10,0,10,10" HorizontalAlignment="Center">
<Controls:ImageButton x:Name="btnCodeConnect" Content="Connect" Height="70" Width="275" Foreground="Black" Style="{DynamicResource PlainButton}" FontFamily="Arial" FontSize="30" FontWeight="Bold" Click="btnCodeConnect_Click" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Controls:ImageButton x:Name="btnCodeCancel" Content="Cancel" Height="70" Width="275" Foreground="Black" Style="{DynamicResource PlainButton}" FontFamily="Arial" FontSize="30" FontWeight="Bold" Click="btnCodeCancel_Click" HorizontalAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
</Grid>
</Border>
<Border Grid.Row="2" x:Name="brdrKbd" Background="White" CornerRadius="20" Width="1200" Height="420"/>
</Grid>
</Popup>
Here's what I'm currently trying to do during the listview click event to get focus to the control. Note that I tried to fake the "set focus to the listview, then set it to the textbox, but that didn't work.
// set the popup location and width and keyboard border width based on the current screen width
popPasscode.IsOpen = true;
// open the on-screen keyboard - synchronous call, doesn't return until it's open and idle
FocusManager.SetFocusedElement(this, lvAvailNetworks);
tbPasscode.Focusable = true;
FocusManager.SetFocusedElement(popPasscode, tbPasscode);
I've tried a couple different things for the DependencyElement for tbPasscode, but I really have no idea what I'm doing, or that what I'm doing is making any difference. Oh, did I mention I just finished my first week of WPF coding? Yup, WPF newbie alert.
I saw this post, but it didn't help much, since I thought I was already doing all that.
Instead of MouseDown, register to MouseUp event on ListView/ListViewItem.
In the handler you can do
popPasscode.IsOpen = true;
Keyboard.Focus(tbPasscode);
The MouseUp on your ListView takes focus away from the Popup, so open your Popup in MouseUp instead of MouseDown
NOTE: This is one of the first time I'm using WPF.
I am trying to align a certain control, let's say a button for now, in the bottom right corner. But when I debug my application, it misses 8 pixels to the bottom and right. I will attach 2 pictures to show you what happens.
How do I keep the button in place?
My XAML code:
<Window x:Class="Plugin_Manager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Plugin Manager" Height="350" Width="525" Loaded="Window_Loaded_1">
<Grid x:Name="GridMain">
<Button Content="Refresh" Margin="432,288,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="75"/>
<ListView HorizontalAlignment="Left" Height="273" Margin="10,10,0,0" VerticalAlignment="Top" Width="497">
<ListView.View>
<GridView>
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
</Grid>
If you choose to use Grid layout you should try to avoid placing objects via Margin. Margin should be used to create buffer around an object, not move it to a specific point in the window. Use the layout manager's power to your advantage!
Here is a Grid example that does what you are looking for.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Grid.Row="0" />
<Button Grid.Row="1" HorizontalAlignment="Right" Content="Push Me" />
</Grid>
I would also read up on Layout Manager in WPF. There are several; each having its own advantages & disadvantages.
Here is a DockPanel version.
<DockPanel>
<Button DockPanel.Dock="Bottom" HorizontalAlignment="Right" Content="Push Me" />
<ListView />
</DockPanel>
To create your buffer between the button and the window chrome you could do a few different things:
<Grid Margin="10"> will apply a 10 pixel space between all content and the window chrome on all side.
<Grid Margin="0,0,10,10"> would indent all content, but only on the right & bottom.
<Grid Margin="10,0,10,10"> indents all around, except the top (I commonly do this one, with a different margin value).
<Button Margin="0,0,10,10"> would indent only the button from the chrome (this is the direct answer to your comment question).
Replace the Grid above with DockPanel for the second example, or whatever other Layout Manager you are using.
A usability side note: Your confirmation buttons (I'm assuming your button will be an Ok/Cancel type button) should not be indented differently from the rest of your content. All controls that butt up against the right margin should do so at the same point (i.e., you can draw a vertical line down the right side of them all).
So, using your question's example: your button should not be indented 10 pixels to the right while your list box is not. Keeping things lined up will improve the overall look to your application.
(this ends my "usability and look-and-feel is important" side note) :)
<Button VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5"/>
Some code example will help. Try using the alignment in xaml for your button as shown below. Ensure that the margins on the button are 0.
<Button Margin="0" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
Looking at the sample code, it is your margins and the alignment you have that are probably causing that.
Just some pointers that may help. Instead of using large margins to align the controls, I find it much easier to work with Column and Row definitions on the grid. This way you can align your controls using the grid and they will size properly as you resize your window. I attached an example in hopes it helps in your new adventures with WPF!
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Version Date" Margin="3" VerticalAlignment="Center"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding DateSubmitted}" Margin="3"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="Report" Margin="3" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding ReportName}" Margin="3"/>
</Grid>
I have a xaml code:
<Grid>
<WrapPanel>
<TextBox ></TextBox>
<Button Content="GetIt" />
</WrapPanel>
</Grid>
How i can to get all available space for textBox?
i want to do something like that:
|[____________________][GetIt]|
There are a number of ways this can be achieved, including this one:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox />
<Button Grid.Column="1">GetIt</Button>
</Grid>
Try this:
<Grid>
<TextBox HorizontalAlignment="Stretch" Margin="2,2,102,2"></TextBox>
<Button HorizontalAlignment="Right" Width="100" Content="GetIt" />
</Grid>
Just make the button the desired width and the text box will fill up the rest.
Thanks for the catch; corrected above to properly handle margin on right. This does, however, require you to update the margin when the button width changes. Two columns is a better solution if you plan to change the spacing often. Using the margin is cleaner if you have several controls in the grid and don't want to create nested grids to handle this kind of split.
The simplest way is to use a DockPanel instead of a Grid (the default for LastChildFill is true but I also added it here for clarity):
<DockPanel LastChildFill="True">
<Button Content="GetIt" DockPanel.Dock="Right" />
<TextBox ></TextBox>
</DockPanel>
Here's a way to achieve the layout that you're looking for:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="2"/>
</Style>
</Page.Resources>
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<!-- Because the Button is fixed in size, you can divide the row it's
in using a DockPanel: the Button is docked to the right edge, and the
TextBox fills up the remaining available space. -->
<Button Margin="2" Padding="2" DockPanel.Dock="Right">GetIt</Button>
<TextBox />
</DockPanel>
<!-- Because the TextBoxes *aren't* fixed in size, you can't use docking,
as it won't size them. So put them in a Grid and use star sizing to
divide the grid's vertical space into two equal parts. The Grid will
fill up the remainder of the (outer) DockPanel. -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0">Another TextBox</TextBox>
<TextBox Grid.Row="1">Yet another TextBox</TextBox>
</Grid>
</DockPanel>
</Page>