UWP - How do I center a button? - c#

I created a UWP solution and created a button. There are no problems with the buttons.
I do not know how to center the button in the window.
Code
StackPanel stackPanel1 = new StackPanel();
Button TestButton = new Button();
TestButton.Content = "Test";
stackPanel1.Children.Add(subscribeButton);
Window.Current.Content = stackPanel1;

This line is all you need.
TestButton.HorizontalAlignment = HorizontalAlignment.Center;

Changing the position of the button to half of the form's width and height will work.
Point point = new Point(this.Width / 2 - (button1.Width/2), this.Height / 2 - (button1.Height/ 2));
button1.Location = point;
The added - (button1.Width/2) is because the button's position is based on the upper right hand corner of the button, and not actually the center.

You can set HorizontalAlignment something like these inside the stackpanel...
<StackPanel Margin="10,0,0,0" Orientation="Horizontal" Grid.Column="0">
<TextBlock Grid.Column="1" Grid.Row="0" FontSize="16" HorizontalAlignment="Center">2. Draw a pattern</TextBlock>
<Button x:Name="DeleteSiteButton" Content="Delete Site"
HorizontalAlignment="Right" Margin="0,0,0,0" VerticalAlignment="Top" Click="DeleteSiteButton_Click"/>
<Button x:Name="AddSiteButton" Content="Add Site" HorizontalAlignment="Right"
Margin="10,0,0,0" VerticalAlignment="Top" Click="AddSiteButton_Click"/>
</StackPanel>

StackPanel control arranges child elements into a single line that can be oriented horizontally or vertically. When the Orientation property is set to Vertical(The default value is Vertical), the VerticalAlignment property of the button control will be invalid. Similarly, when the Orientation property is set to Horizontal, the HorizontalAlignment property of the button control will be invalid.
If you add a button control into a StackPanel, the HorizontalAlignment property and VerticalAlignment property of the button control will not work at the same time, that is, the button control can not be centered in a StackPanel.
We suggest that you could add the button control to a Grid panel, like this:
Grid gridPanel1 = new Grid();
Button TestButton = new Button();
TestButton.Content = "Test";
TestButton.HorizontalAlignment = HorizontalAlignment.Center;
TestButton.VerticalAlignment = VerticalAlignment.Center;
gridPanel1.Children.Add(TestButton);
Window.Current.Content = gridPanel1;

Related

UWP XAML Popup not respecting VerticalAlignment?

I'm trying to center a Popup in a Windows Store/UWP app.
In brief, I'm taking MainPage and adding...
A TextBlock with some text
A Button with an event handler, Button_Click
A Popup named popupTest. It contains...
A Border with...
A StackPanel with
A TextBlock
A Button. This Button's event handle sets the Popup's IsOpen to false.
Button_Click calls _centerPopup, which tries to center the Popup and then sets IsOpen to true. I can't get this to work.
private void _centerPopup(Popup popup, Border popupBorder, FrameworkElement extraElement = null)
{
double ratio = .9; // How much of the window the popup fills, give or take. (90%)
Panel pnl = (Panel)popup.Parent;
double parentHeight = pnl.ActualHeight;
double parentWidth = pnl.ActualWidth;
// Min 200 for each dimension.
double width = parentWidth * ratio > 200 ? parentWidth * ratio : 200;
double height = parentHeight * ratio > 200 ? parentHeight * ratio : 200;
popup.Width = width;
popup.Height = height;
//popup.HorizontalAlignment = HorizontalAlignment.Center;
popup.VerticalAlignment = VerticalAlignment.Top; // <<< This is ignored?!
// Resize the border too. Not sure how to get this "for free".
popupBorder.Width = width;
popupBorder.Height = height;
// Not using this here, but if there's anything else that needs resizing, do it.
if (null != extraElement)
{
extraElement.Width = width;
extraElement.Height = height;
}
}
If I don't try to resize and center the Popup in Button_Click, here's what I get after clicking "Click Me"...
private void Button_Click(object sender, RoutedEventArgs e)
{
//_centerPopup(this.popupTest, this.popupTestBorder);
this.popupTest.IsOpen = true;
}
If I uncomment out the call to _centerPopup, I get this, with the popup staying under the button:
private void Button_Click(object sender, RoutedEventArgs e)
{
_centerPopup(this.popupTest, this.popupTestBorder);
this.popupTest.IsOpen = true;
}
That's no good. I thought popup.VerticalAlignment = VerticalAlignment.Top; would've fixed that.
FrameworkElement.VerticalAlignment Property
Gets or sets the vertical alignment characteristics applied to this element when it is composed within a parent element such as a panel or items control.
Move Popup to top of StackPanel?
Strangely, if I move the Popup up to the top of my StackPanel, it actually pushes the other controls down after being shown.
Clicking "Click Me" without _centerPopup:
That looks promising! It's floating over the other controls nicely, and there's no obvious impact to the layout after it's closed.
But add back _centerPopup, even after commenting out setting VerticalAlignment to Top, and things die a horrible, fiery death.
It looks perfect until you notice that every other control was pushed down. ??? Here's after clicking "Click to close":
Other controls are pushed down permanently. Why does that happen? Shouldn't the popup float like it did before I resized it?
Full Source
XAML
<Page
x:Class="PopupPlay.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PopupPlay"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Name="StackMain">
<TextBlock>
This is some text<LineBreak />
This is some text<LineBreak />
This is some text<LineBreak />
This is some text<LineBreak />
</TextBlock>
<Button Click="Button_Click" Content="Click Me"></Button>
<Popup x:Name="popupTest">
<Border
Name="popupTestBorder"
Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
BorderBrush="{StaticResource ApplicationForegroundThemeBrush}"
BorderThickness="2">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Name="txtPopup"
Text="This is some text"
FontSize="24"
HorizontalAlignment="Center" />
<Button Name="btnClose"
Click="btnClose_Click"
Content="Click to close"></Button>
</StackPanel>
</Border>
</Popup>
</StackPanel>
</Page>
Full MainPage.xaml.cs code
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
namespace PopupPlay
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_centerPopup(this.popupTest, this.popupTestBorder);
this.popupTest.IsOpen = true;
}
private void _centerPopup(Popup popup, Border popupBorder, FrameworkElement extraElement = null)
{
double ratio = .9; // How much of the window the popup fills, give or take. (90%)
Panel pnl = (Panel)popup.Parent;
double parentHeight = pnl.ActualHeight;
double parentWidth = pnl.ActualWidth;
// Min 200 for each dimension.
double width = parentWidth * ratio > 200 ? parentWidth * ratio : 200;
double height = parentHeight * ratio > 200 ? parentHeight * ratio : 200;
popup.Width = width;
popup.Height = height;
//popup.HorizontalAlignment = HorizontalAlignment.Center;
popup.VerticalAlignment = VerticalAlignment.Top; // <<< This is ignored?!
// Resize the border too. Not sure how to get this "for free".
popupBorder.Width = width;
popupBorder.Height = height;
// Not using this here, but if there's anything else that needs resizing, do it.
if (null != extraElement)
{
extraElement.Width = width;
extraElement.Height = height;
}
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
this.popupTest.IsOpen = false;
}
}
}
There are several questions that seem related. I do not see a viable fix. (Note: These are not all UWP specific.)
Center Popup in XAML
Place Popup at top right corner of a window in XAML
How to set vertical offset for popup having variable height
Painfully, this same setup is working for me in another app when it's positioned in a much more complicated grid with a Pivot, but I see that pivots are buggy.
Wpf's Placement stuff sounds promising, but doesn't exist in UWP-land.
Your Popup is inside a vertical StackPanel, which means the StackPanel will lay out the popup alongside the other child elements of the panel, which is why it pushes down the text.
Also, the VerticalAlignment is being ignored by the panel because the panel allocated exactly enough vertical space for the popup's size, and so there is no room for it to align the popup vertically within the space it was allocated.
I would suggest using a Grid as the root element for the Page, and putting the StackPanel and Popup directly inside the Grid, like this:
<Grid>
<StackPanel Name="StackMain">
<TextBlock>
This is some text<LineBreak />
This is some text<LineBreak />
This is some text<LineBreak />
This is some text<LineBreak />
</TextBlock>
<Button Click="Button_Click" Content="Click Me"></Button>
</StackPanel>
<Popup x:Name="popupTest">
<Border
Name="popupTestBorder"
Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
BorderBrush="{StaticResource ApplicationForegroundThemeBrush}"
BorderThickness="2">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Name="txtPopup"
Text="This is some text"
FontSize="24"
HorizontalAlignment="Center" />
<Button Name="btnClose"
Click="btnClose_Click"
Content="Click to close"></Button>
</StackPanel>
</Border>
</Popup>
</Grid>
Grids are good for this purpose, when you want to have overlapping elements or multiple elements that do not affect the position and size of any other child element. You want the layout of the popup to be separate from the layout of the stack panel and its children, so you should organize your XAML as such.
Try changing your xaml as follows...
<Page...>
<Grid x:Name="LayoutRoot">
<Popup>
</Popup>
<Grid x:Name="ContentPanel">
</Grid>
</Grid>
</Page>
So move the Popup control outside the content area and put your stacklayout with all content inside the ContentPanel Grid ( as shown in code sample above )
That should stop pushing the other controls down...

How to add a button with Tooltip, Transparent background and Glyph from code?

In XAML, you can add a button like this:
<Button Height="Auto" Width="Auto" Background="Transparent" ToolTipServie.ToolTip="Tooltip here" ToolTipService.Placement="Bottom" />
However I cannot achieve similar approach with C#. Assume I have a Stackpanel named "toolbar":
toolbar.Children.Add(new Button {
Name = "undo",
FontFamily = new FontFamily("Segoe MDL2 Assets"),
Content = "&#xE10E",
Opacity = 100,
});
When I debug the code, it adds a button with squares, gray background. Also I don't know how to add a tooltip to the button.
I tried searching for help, nothing helped. :(
Any help is much appreciated. Thanks.
The tooltip isn't a normal DP, it's an attached property via the ToolTipService class, so you need to add it as such:
var button = new Button
{
Name = "undo",
FontFamily = new FontFamily("Segoe MDL2 Assets"),
Content = "&#xE10E",
Opacity = 100,
};
ToolTipService.SetToolTip(button, "Tooltip here");
ToolTipService.SetPlacement(button, PlacementMode.Bottom);
toolbar.Children.Add(button);

How to change the position of dynamic buttons in wp8 c#

In my windows phone application I am creating a dynamic button like below:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="24,0,0,0">
<TextBox x:Name="tb_groupname"
Height="90"
Background="White"
Margin="0,0,125,517"
Foreground="Blue" TextChanged="tb_groupname_TextChanged" GotFocus="tb_groupname_GotFocus" LostFocus="tb_groupname_LostFocus"/>
<Button x:Name="btn_groupname"
Content="Add"
Background="AliceBlue"
Foreground="Blue"
FontSize="25"
Width="120"
Height="90"
HorizontalAlignment="Right"
VerticalAlignment="Top" Click="btn_groupname_Click"></Button>
<ListBox x:Name="lb_groupofcontacts" ItemsSource="{Binding}" Margin="0,118,0,0">
</ListBox>
And below is the xaml.cs page code
private void btn_groupname_Click(object sender, RoutedEventArgs e)
{
if (tb_groupname.Text != string.Empty)
{
List<Button> buttons = new List<Button>();
Button btn = new Button();// Cast the control to Button.
btn.Content = tb_groupname.Text;
btn.Width = 200;
btn.Height = 200;
btn.Click += new RoutedEventHandler(btn_Click); // Add event to button.
buttons.Add(btn);
buttonName = tb_groupname.Text;
tb_groupname.Text = string.Empty;
lb_groupofcontacts.DataContext = buttons;
}
}
And add button into listbox lb_groupofcontacts but when I create another dynamic button it map onto the previous button means it not change the position of the button
And I want that
first button created on top left
second button created on top right
third button created on center left
forth button created on center right
fifth button created on bottom left
sixth button created on botton right
Kindly suggest me how do I change the position of the like above or if you know any other way to change the position of dynamic both then tell me, waiting for your reply.
Thanks.
First of all You are creating object of list into Button_click so every time it is creating new list and adds only new one button and taking that list as listbox's Content so you are not able to add Second Button.
You can set Position of Button Dynamically by:
btn.Margin = new Thickness(LEFT,TOP,RIGHT,BOTTOM);
OR
btn.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
btn.VerticalAlignment = System.Windows.VerticalAlignment.Center;
You can manipulate Button's position by setting its Margin property to different values ("0, 0" for the first button, "0, 200" for the second one and so on).
But that's not very good approach, the right way depends on what you need to do. I'd suggest to replace ListBox with Grid having 6 cells as the most simple decision.

How to set two alignment in wrappanel

How can I get a wrappanel like the pics below? The two button < > and textblock align to left, and the textbox align to right, when I resize width of windows, the textbox auto wrap to new line.
Here is a quick and dirty way of doing it.
<WrapPanel Orientation="Horizontal" SizeChanged="WrapPanel_SizeChanged">
<TextBlock x:Name="DateTextBlock" TextWrapping="Wrap" MinWidth="280"><Run Text="July 03-09, 2011"/></TextBlock>
<TextBox x:Name="SearchTextBox" Width="250" HorizontalAlignment="Right" />
</WrapPanel>
Then in your your WrapPanel_SizeChanged handler you simply make the DataTextBlock as wide as possible - as wide as the panel less the width of the Search TextBox.
private void WrapPanel_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
{
var panel = (WrapPanel)sender;
var maxWidth = panel.ActualWidth - SearchTextBox.ActualWidth;
DateTextBlock.Width = maxWidth;
}

How to add a StackPanel in a Button in C# code behind

How to add a StackPanel in a Button using c# code behind (i.e. convert the following XAML to C# )? There is no Button.Children.Add...
<Button>
<StackPanel Orientation="Horizontal" Margin="10">
<Image Source="foo.png"/>
</StackPanel>
</Button>
Image img = new Image();
img.Source = new BitmapImage(new Uri("foo.png"));
StackPanel stackPnl = new StackPanel();
stackPnl.Orientation = Orientation.Horizontal;
stackPnl.Margin = new Thickness(10);
stackPnl.Children.Add(img);
Button btn = new Button();
btn.Content = stackPnl;
Set Button.Content instead of using Button.Children.Add
As a longer explanation:
Button is a control which "only has 1 child" - its Content.
Only very few controls (generally "Panels") can contain a list of zero or more Children - e.g. StackPanel, Grid, WrapPanel, Canvas, etc.
As your code already shows, you can set the Content of a Button to be a Panel - this would ehn allow you to then add multiple child controls. However, really in your example, then there is no need to have the StackPanel as well as the Image. It seems like your StackPanel is only adding Padding - and you could add the Padding to the Image rather than to the StackPanel if you wanted to.
Use like this
<Window.Resources>
<ImageSource x:Key="LeftMenuBackgroundImage">index.jpg</ImageSource>
<ImageBrush x:Key="LeftMenuBackgroundImageBrush"
ImageSource="{DynamicResource LeftMenuBackgroundImage}"/>
</Window.Resources>
and in Codebehind
Button btn = new Button();
btn.HorizontalContentAlignment = HorizontalAlignment.Stretch;
btn.VerticalContentAlignment = VerticalAlignment.Stretch;
StackPanel stk = new StackPanel();
stk.Orientation = Orientation.Horizontal;
stk.Margin = new Thickness(10, 10, 10, 10);
stk.SetResourceReference(StackPanel.BackgroundProperty, "LeftMenuBackgroundImageBrush");
btn.Content = stk;
In Xaml :
<Button x:Name="Btn" Click="Btn_Click" Orientation="Horizontal" Margin="10">
<StackPanel>
<Image Source="foo.png" Height="16" Width="16"/>
</StackPanel>
</Button>
In C# :
Button btn = new Button();
StackPanel panel = new StackPanel();
Image img = new Image
{
Source = "../foo.png"
}
panel.Children.Add(img);
btn.Content = panel;
I advise you to put the image in xaml resources :
<Window.Resources>
<BitmapImage x:Key="Img" UriSource="/Img/foo.png"/>
</Window.Resources>
And call it like this :
Image img = new Image
{
Source = (BitmapImage)FindResource("Img")
};

Categories