align image to the right inside a button programmatically WPF - c#

I'm trying to align a image inside a button to the right. however it does not seem to do what i want it to do. i have been trying for several hours now, so i think it is time to ask here. this is my code atm.
public class DirectoryButton : Button
{
public DirectoryButton(string name, string content)
{
Name = name.Replace(" ", "");
//Content = new BitmapImage(new Uri("../Resources/folder-icon.png", UriKind.Relative)) + content;
//Content = new BitmapImage(new Uri("../Resources/folder-icon.png", UriKind.Relative));
var img = new BitmapImage(new Uri("../Resources/folder-icon.png", UriKind.Relative));
var sp = new UniformGrid
{
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
Columns = 3,
Rows = 1
};
sp.Children.Add(new Label());
sp.Children.Add(new Label { Content = content, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center });
sp.Children.Add(new Image { Source = img, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center});
//sp.Orientation = Orientation.Horizontal;
Content = sp;
//Content = content;
Margin = new Thickness(0, 5, 0, 5);
Height = 65;
Width = 350;
FontWeight = FontWeights.Bold;
Foreground = new SolidColorBrush(Colors.Black);
Background = new SolidColorBrush(Colors.Gray);
HorizontalContentAlignment = HorizontalAlignment.Center;
VerticalAlignment = VerticalAlignment.Center;
Visibility = Visibility.Visible;
}
}
button Image
this makes the image in the button appear but it is not to the right. i cannot really do anything in the xaml since everything is created programmaticaly.
Regards,
Bjorn

Set the HorizontalContentAlignment to Stretch:
public class DirectoryButton : Button
{
public DirectoryButton(string name, string content)
{
Name = name.Replace(" ", "");
//Content = new BitmapImage(new Uri("../Resources/folder-icon.png", UriKind.Relative)) + content;
//Content = new BitmapImage(new Uri("../Resources/folder-icon.png", UriKind.Relative));
var img = new BitmapImage(new Uri("../Resources/folder-icon.png", UriKind.Relative));
var sp = new UniformGrid
{
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
Columns = 3,
Rows = 1
};
sp.Children.Add(new Label());
sp.Children.Add(new Label { Content = content, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center });
sp.Children.Add(new Image { Source = img, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center });
//sp.Orientation = Orientation.Horizontal;
Content = sp;
//Content = content;
Margin = new Thickness(0, 5, 0, 5);
Height = 65;
Width = 350;
FontWeight = FontWeights.Bold;
Foreground = new SolidColorBrush(Colors.Black);
Background = new SolidColorBrush(Colors.Gray);
HorizontalContentAlignment = HorizontalAlignment.Stretch; //<--
VerticalAlignment = VerticalAlignment.Center;
Visibility = Visibility.Visible;
}
This should make the UniformGrid stretch to fill the entire Button and the Image will then end up to the right.

As I tried to explain in the comments above.
The code you've provide us works like it should.
You create an UniformGrid with three cells and add three childs to the grid.
Each cell of the grid will have the same size.
Your empty label will got to the left one. The next label to the center.
You will add your image to the right cell and set HorizontalAlignment = HorizontalAlignment.Right. This will align your image within his cell at the right edge. And also to the right edge of your grid.
Now you add your UniformGrid as Content to your button.
With the following line of code
HorizontalContentAlignment = HorizontalAlignment.Center;
you will center your grid within the button.
That's why your image is not at the right edge of your button.
As already suggested in my comment you can set
HorizontalContentAlignment = HorizontalAlignment.Right;
and your Image and the whole grid will move to the right edge, but this means also that your centered Label will also move to the right.
If you want to let the second Label stay within the center of the Button take the Answer provided by mm8 and use
HorizontalContentAlignment = HorizontalAlignment.Stretch;

Related

Custom button not rendering correctly

I've got a custom class for a button with a circular image as I'll be using it multiple times through my program. I thought it'd be pretty simple of creating class, inheriting from Button and slapping my setup into a constructor, but when I'm running the program the buttons are massive and plain (no image or text). Here's my class:
public class ImageButton : Button
{
public Button Button;
public ImageButton(string filename) : this(HorizontalAlignment.Center, VerticalAlignment.Center, filename)
{ }
public ImageButton(HorizontalAlignment hAlignment, VerticalAlignment vAlignment, string filename)
{
Button = new Button
{
Width = 35,
Height = 35,
Background = Brushes.Transparent,
HorizontalAlignment = hAlignment,
BorderBrush = Brushes.Transparent,
VerticalAlignment = vAlignment,
Content = new Image
{
Source = new BitmapImage(new Uri("pack://application:,,,/Resources/" + filename))
}
};
}
}
And here's my implementation of one of the instances
private void SetupHeaders(Grid resultGrid)
{
RowDefinition backbtn = new RowDefinition();
backbtn.Height = new GridLength(0.2, GridUnitType.Star);
resultGrid.RowDefinitions.Add(backbtn);
btn_Return = new ImageButton(HorizontalAlignment.Left, VerticalAlignment.Top, "returnicon.png");
Grid.SetRow(btn_Return, 0);
Grid.SetColumn(btn_Return, 0);
resultGrid.Children.Add(btn_Return);
}
with btn_Return being defined at the top of the class as simply
ImageButton btn_Return;
Here's an image of one of the buttons.
In you constructor you inititalize a Button with you properties and then assign it to a property. You never actually use the initialized button. You are always using ImageButton which is nothing more than an inherited button therefore you get the default behavior.
You have to change your constructor.
public ImageButton(HorizontalAlignment hAlignment, VerticalAlignment vAlignment, string filename)
{
Width = 35;
Height = 35;
Background = Brushes.Transparent;
HorizontalAlignment = hAlignment;
BorderBrush = Brushes.Transparent;
VerticalAlignment = vAlignment;
Content = new Image
{
Source = new BitmapImage(new Uri("pack://application:,,,/Resources/" + filename))
};
}

How to center TextBox element inside Grid

I'm developing WP8 app for my own needs and want it to have small live tile with text.
Since small tile cannot display text, I'm generating appropriate image with needed text.
Here is the code:
WriteableBitmap bmpSmall = new WriteableBitmap(159, 159);
var grid = new Grid();
grid.Width = bmpSmall.PixelWidth;
grid.Height = bmpSmall.PixelHeight;
var background = new Canvas();
background.Width = bmpSmall.PixelWidth;
background.Height = bmpSmall.PixelHeight;
SolidColorBrush backColor = new SolidColorBrush((Color)Application.Current.Resources["PhoneAccentColor"]);
background.Background = backColor;
var textBlock = new TextBlock();
textBlock.Text = "qwerty";
textBlock.FontWeight = FontWeights.Bold;
textBlock.HorizontalAlignment = HorizontalAlignment.Center;
textBlock.VerticalAlignment = VerticalAlignment.Center;
textBlock.FontSize = 28;
textBlock.Foreground = new SolidColorBrush(Colors.White);
grid.Children.Add(textBlock);
bmpSmall.Render(background, null);
bmpSmall.Render(grid, null);
bmpSmall.Invalidate();
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream imageStream = new IsolatedStorageFileStream("/Shared/ShellContent/smallTile.jpg", System.IO.FileMode.Create, isf))
{
bmpSmall.SaveJpeg(imageStream, 159, 159, 0, 100);
}
}
ShellTile tile = ShellTile.ActiveTiles.First();
FlipTileData tileData = new FlipTileData();
tileData.SmallBackgroundImage = new Uri(#"isostore:/Shared/ShellContent/smallTile.jpg", UriKind.Absolute);
tile.Update(tileData);
And result looks like:
As you see, text is aligned to top left corner. The question is "Why"? Since I'd set textBlock.HorizontalAlignment and textBlock.VerticalAlignment - I expect it in the center of the image.
For example the following XAML looks like you can expect and like I need:
<Grid Width="159" Height="159">
<Grid.Background>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}"/>
</Grid.Background>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" FontSize="28" Foreground="White">qwerty</TextBlock>
</Grid>
What did I miss? How can I center text?
Give the following code a try:
WriteableBitmap bmpSmall = new WriteableBitmap(159, 159);
var grid = new Grid();
grid.Width = bmpSmall.PixelWidth;
grid.Height = bmpSmall.PixelHeight;
var background = new Canvas();
background.Width = bmpSmall.PixelWidth;
background.Height = bmpSmall.PixelHeight;
SolidColorBrush backColor = new SolidColorBrush((Color)Application.Current.Resources["PhoneAccentColor"]);
background.Background = backColor;
var textBlock = new TextBlock();
textBlock.Width = bmpSmall.PixelWidth;
textBlock.Text = "qwerty";
textBlock.FontWeight = FontWeights.Bold;
textBlock.HorizontalAlignment = HorizontalAlignment.Stretch;
textBlock.VerticalAlignment = VerticalAlignment.Center;
textBlock.FontSize = 28;
textBlock.Foreground = new SolidColorBrush(Colors.White);
textBlock.TextAlignment = TextAlignment.Center;
grid.Children.Add(background);
grid.Children.Add(textBlock);
grid.Measure(new Size(bmpSmall.PixelWidth, bmpSmall.PixelHeight));
grid.Arrange(new Rect(0,0,bmpSmall.PixelWidth, bmpSmall.PixelHeight));
grid.UpdateLayout();
bmpSmall.Render(grid, null);
bmpSmall.Invalidate();
I set the TextBlock width to the same as the rest of the tile, and set HorizontalAlignment to stretch, so that control would take up the whole width of the tile. Then I set the TextAlignment property to TextAlignment.Center, in order to center the text. Hope that helps!
Edit: Apparently for writable bitmaps, you must do the measure/arrange/layout steps yourself in order to render controls as you would think they should be rendered. Give this updated code a try, it should work this time!
You will have to set the HorizontalAlignment="Stretch" VerticalAlignment="Stretch" for grid also. Currently grid is only of size of its content i.e textblock.
After copying your code into an empty WPF application, I'm afraid to tell you that your code works just fine:
All I did was to set the Grid.Background to red and the TextBlock.Background to black to clarify the situation:
<Grid Width="159" Height="159">
<Grid.Background>
<SolidColorBrush Color="Red"/>
</Grid.Background>
<TextBlock Background="Black" HorizontalAlignment="Center"
VerticalAlignment="Center" FontWeight="Bold" FontSize="28"
Foreground="White">qwerty</TextBlock>
Therefore, I can only assume that you have a problem elsewhere in your code.
UPDATE >>>
Sorry, you're right, I did misunderstand you. However, after testing your C# code, the story is just the same:
This might look like the same image, but it actually comes from your C# code... I made a couple of little changes, but nothing that affected the position of the TextBlock:
Grid grid = new Grid();
grid.Background = Brushes.Red;
grid.Width = grid.Height = 159.0;
TextBlock textBlock = new TextBlock();
textBlock.Text = "qwerty";
textBlock.Background = Brushes.Black;
textBlock.FontWeight = FontWeights.Bold;
textBlock.HorizontalAlignment = HorizontalAlignment.Center;
textBlock.VerticalAlignment = VerticalAlignment.Center;
textBlock.FontSize = 28;
textBlock.Foreground = Brushes.White;
grid.Children.Add(textBlock);
this.Content = grid;
If you put this code into a new WPF project, you'll see that it works just fine, so that only leaves your WriteableBitmap object as the culprit of this problem... what are you using that for? If you're just adding it to your UI, then you can simply add the controls to the Window directly.

Rotated textblock doesn't have the correct length

I am trying to fill a Grid in a WPF application dynamically.
I'm creating a row and then some columns. in each column I am adding a textblock, like this:
GrdMainGrid.RowDefinitions.Add(new RowDefinition(Height = new GridLength(150, GridUnitType.Pixel);
GrdMainGrid.RowDefinitions.Add(new RowDefinition(Height = new GridLength(1, GridUnitType.Star);
for(var i=0; i<4; i++)
{
GrdMainGrid.ColumnDefinitions.Add(new ColumnDefinition {With = new GridLength(25, GridUnitType.Pixel)});
}
var header = new TextBlock {Text = "Header1", RenderTransform = new RotateTransform(-90), Width = 150, Margin = new Thickness(0), VerticalAlignment = VerticalAlignment.Bottom, HorizontalAlignment = HorizontalAlignment.Left};
.
.
.
Grid.SetColumn(header, 0);
Grid.SetRow(header, 0);
.
.
.
GrdMainGrid.Children.Add(header);
The textblock is rotated -90 degree.
While the size of the column is set to 25 pixel i doesn't show all text, when I increase the size of the column the text in textblock is also increased. see pic
I could understand this if the textblock wasn't rotated and it didn't fit in the column. But what has it to do with the size of the column when it's rotated.
And is it possible somehow to decrease the width of the column without decreasing size of text ?
Tnx in advance.
Use a LayoutTransform instead of a RenderTransform.
var header = new TextBlock { Text = "Header1", LayoutTransform = new RotateTransform(-90), Width = 150, Margin = new Thickness(0), VerticalAlignment = VerticalAlignment.Bottom, HorizontalAlignment = HorizontalAlignment.Left };

Can't get dynamically generated tile working (Windows Phone)

I have the method, which is executed in Application_Deacitvated/Closing().
public bool createBackTile()
{
if(AlarmClock.IsExists())
{
ImageBrush background = new ImageBrush()
{
ImageSource = new BitmapImage(new Uri("/BackBackgroundTheme.png", UriKind.Relative)),
AlignmentX = AlignmentX.Center,
AlignmentY = AlignmentY.Center
};
// Preparing tile image.
TextBox tileImageData = new TextBox()
{
Text = AlarmClock.Read().ToShortTimeString(),
FontSize = 45,
FontWeight = FontWeights.Bold,
Foreground = new SolidColorBrush(Colors.White),
//Background = background,
Height = 173,
Width = 173,
HorizontalContentAlignment = HorizontalAlignment.Center,
VerticalContentAlignment = VerticalAlignment.Center,
Padding = new Thickness(-12),
Margin = new Thickness(0),
Clip = new RectangleGeometry { Rect = new Rect(0, 0, 173, 173) }
};
Canvas canvas = new Canvas()
{
Width = 173,
Height = 173,
Background = background,
Margin = new Thickness(0)
};
canvas.Children.Add(tileImageData);
// Saving tile image.
WriteableBitmap tileImage = new WriteableBitmap(173, 173);
tileImage.Render(canvas, null);
tileImage.Render(tileImageData, null);
tileImage.Invalidate();
using(var stream = IsolatedStorageFile.GetUserStoreForApplication().CreateFile("/Shared/ShellContent/BackBackground.jpg"))
{
tileImage.SaveJpeg(stream, 173, 173, 0, 100);
}
// Sets data for tile.
StandardTileData tileData = new StandardTileData()
{
BackgroundImage = new Uri("BackgroundAlarmSet.png", UriKind.Relative),
BackBackgroundImage = new Uri(#"isostore:/Shared/ShellContent/BackBackground.jpg"),
BackContent = "",
BackTitle = "",
};
// Sets tile.
ShellTile.ActiveTiles.FirstOrDefault().Update(tileData);
return true;
}
return false;
}
So, as you can see, I want to generate tile with my text in the center of it with image background "BackBackgroundTheme.png". That tile I'm trying to save in IsolatedStorage and assign it to BackBackgroundImage.
But it doesn't work. The tile is flipping over but the BackBackground is completly black. I have loaded this manipulated background and it seems that's indeed just black box. So, how to get it working?
Try: BackgroundImage = new Uri(#"isostore:/Shared/ShellContent/BackBackground.jpg", UriKind.Absolute)
I have finally found out where the problem is.
It seems, that generation of tile image isn't done properly in Application_Closing/Deactivating(). So I moved image generation to somwhere else and now, when application is closing/deactivating, I just set previously generated image to a tile.
Try this:
canvas.Children.Add(tileImageData);
canvas.UpdateLayout();
// Saving tile image.
WriteableBitmap tileImage = new WriteableBitmap(173, 173);

Setting tooltip width and height dynamically

In WPF (C#) is there a way to set the tooltip's height and width dynamically (meaning in code). Thanks for the help.
System.Windows.Controls.Image td = new System.Windows.Controls.Image();
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(Directory.GetCurrentDirectory() + "/Homepage.jpg");
td.Width = 530;
td.Height = 392;
//myBitmapImage.DecodePixelWidth = 430;
//myBitmapImage.DecodePixelHeight = 292;
myBitmapImage.EndInit();
td.Source = myBitmapImage;
TextBlock textBlock = new TextBlock();
BrushConverter conv = new BrushConverter();
string strColor1 = bannerColor.SelectedItem.ToString();
strColor1 = strColor1.Substring(strColor1.IndexOf(' ') + 1);
SolidColorBrush col = conv.ConvertFromString(strColor1) as SolidColorBrush;
textBlock.Foreground = col;
textBlock.FontWeight = FontWeights.Bold;
textBlock.FontSize = 18;
textBlock.FontFamily = new System.Windows.Media.FontFamily("Tahoma");
textBlock.Width = 100;
textBlock.Height = 20;
textBlock.Text = "BACKUP";
textBlock.Margin = new Thickness(5, 5, 425, 367);
Grid toolTipPanel = new Grid();
toolTipPanel.Width = 530;
toolTipPanel.Height = 392;
toolTipPanel.Children.Add(td);
toolTipPanel.Children.Add(textBlock);
ToolTipService.SetToolTip(image1, toolTipPanel);
ToolTipService.SetShowDuration(image1, 999999999);`
In your code just set the tooltip's height and width property to Double.NaN to have the width and height adjust dynamically.
_toolTip.Width = Double.NaN;
_toolTip.Height = Double.NaN;
This will do the trick.
A tool tip's height and width are based on its content. So you should simply make the content the size you want it to be.
Perhaps you could post your code that sets the tool tip, for further clarification?

Categories

Resources