I have a Window with a canvas that has a rectangle at the top of it. It will stretch to fill the width if the canvas. The Canvas is set to be maximized with no toolbar to fill the entire screen like so:
<Window x:Class="Ericsson.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:Ericsson"
mc:Ignorable="d"
Title="MainWindow" WindowStyle="None"
WindowState="Maximized">
<Window.Resources>
<SolidColorBrush x:Key = "brushResource" Color = "Black" />
</Window.Resources>
<Canvas x:Name="MyCanvas" >
<Rectangle x:Name="TopRect" Fill="Black" Height="120" Canvas.Top="0" Canvas.Left="0" Width="{Binding ElementName=MyCanvas, Path=ActualWidth}"/>
<Label Content="Welcome to My World" Foreground="#FFFFFF" FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
</Canvas>
</Window>
My problem is this, I have a label that needs to be centered inside of the dynamic rectangle. The XAML code above puts the label in the upper left hand corner. So "HorizontalAlignment" and "VerticalAlignment" didn't work.
How do I center the label both horizontally and vertically inside of my rectangle?
Thanks
you can introduce an additional container - Grid - which will align elements properly:
<Canvas x:Name="MyCanvas">
<Grid Width="{Binding ElementName=MyCanvas, Path=ActualWidth}">
<Rectangle x:Name="TopRect" Fill="Black" Height="120" />
<Label Content="Welcome to My World" Foreground="#FFFFFF" FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Canvas>
Related
I have a borderless Window with a Border as root node and Canvas as child.
The canvas is used to draw Polyline by MouseMove.
The border have a DropShadowEffect and this cause a significant drop of performance to draw on Canvas.
I have already seen that some others post suggest to put the Border and Canvas in 2 separate Grid, but this will not work for my case since if I put the Border inside a Grid I lose the shadow effect around the Window.
There is another way to prevent the propagation of the Effect?
This is the xaml code:
<Window x:Class="Test.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:Test"
mc:Ignorable="d"
Title="Test"
Height="600" Width="1000"
Background="{x:Null}"
BorderThickness="0"
BorderBrush="Black"
AllowsTransparency="True"
WindowStyle="None">
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="0"
ResizeBorderThickness="5,5,20,20"/>
</WindowChrome.WindowChrome>
<Border x:Name="borderShadow" Margin="0,0,15,15" BorderThickness="2,1" BorderBrush="Black" Background="#FF355870">
<Border.Effect>
<DropShadowEffect Color="Black"
Direction="315"
BlurRadius="15"
ShadowDepth="10"/>
</Border.Effect>
<Grid Background="#FF355870">
<Canvas x:Name="canvasBoard" Background="#00000000" MouseMove="canvasBoard_MouseMove" MouseDown="canvasBoard_MouseDown" MouseUp="canvasBoard_MouseUp"/>
</Grid>
</Border>
</Window>
You can put the Border alone inside a Grid in this way:
<Grid>
<Border x:Name="borderShadow" Margin="0,0,15,15" BorderThickness="2,1" BorderBrush="Black" Background="#FF355870">
<Border.Effect>
<DropShadowEffect Color="Black"
Direction="315"
BlurRadius="15"
ShadowDepth="10"/>
</Border.Effect>
</Border>
<Grid Background="#FF355870">
<Canvas x:Name="canvasBoard" Background="#00000000" MouseMove="canvasBoard_MouseMove" MouseDown="canvasBoard_MouseDown" MouseUp="canvasBoard_MouseUp"/>
</Grid>
</Grid>
so I have two boxes, and the goal here is to have both boxes have the exact same margins from the edge of the window. Unfortunately, in WPF, you only get the margin from the left side, and not both, so to make sure of that, I have the following formula;
The margin of the second box is equal to the window width minus the margin of the first box minus the size of the box.
And this can be backed up with math, it does work. And so I did get my program to figure this out, since it's reactive. And so now I have this image:
WPF Window
The text in the middle is to prove that this calculation is correct. (just so you know, each box is 500px wide) So, the first number is the margin of the first box. The second is the margin of the second, and the last is the window size. Do the math and you have this equation:
(1936 - 88) - 500 = 1348
And that does work, however, if you look in the image, the box on the right is just a little bit closer to the edge than the one on the left. This happens too if you resize it, it's not just when maximized. What's up, and how can I fix this?
Here is my XAML code:
<Window x:Class="Horizon_Chat.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:Horizon_Chat"
xmlns:i="clr-namespace:Horizon_Chat"
i:WindowEx.ShowIcon = "false"
mc:Ignorable="d"
Title="Horizon Chat" Height="900" Width="1280" WindowStartupLocation="CenterScreen" MinWidth="600" MinHeight="600" WindowState="Maximized">
<Grid>
<TextBlock x:Name="welcomeTitleText" HorizontalAlignment="Center" Margin="0,-200,0,0" TextWrapping="Wrap" Text="Hello Camden!" VerticalAlignment="Center" FontFamily="Muli" FontSize="60"/>
<Border x:Name="topBorder" BorderBrush="#FF646464" BorderThickness="0,0,0,4" HorizontalAlignment="Left" Height="41" VerticalAlignment="Top" Width="1273" Margin="0,32,0,0"/>
<Ellipse Fill="#FF30B44E" HorizontalAlignment="Left" Height="50" Margin="10,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="50" StrokeThickness="3"/>
<Border x:Name="chatsBox" BorderBrush="Black" BorderThickness="3" HorizontalAlignment="Left" Height="250" Margin="58,594,0,0" VerticalAlignment="Top" Width="500"/>
<Border x:Name="friendsBox" BorderBrush="Black" BorderThickness="3" HorizontalAlignment="Left" Height="250" Margin="724,594,0,0" VerticalAlignment="Top" Width="500"/>
</Grid>
</Window>
What you're looking for is a grid, set the ColumnDefinition Widths to your rectangle width + the margin you want. The * used for the middle Column's Width means "Fill up the available space". The Margin parameter is set up as (Left, Top, Right, Bottom). This allows you to specify a right hand Margin.
<Window x:Class="ForStackoverflow.MainWindow"
...
xmlns:local="clr-namespace:ForStackoverflow"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Rectangle Margin="15 0 0 0"
StrokeThickness="5"
Stroke="Black"
Height="80"
Grid.Column="0"/>
<Rectangle Margin="0 0 15 0"
StrokeThickness="5"
Stroke="Black"
Height="80"
Grid.Column="2"/>
</Grid>
</Window>
Here's some XAML:
<Grid Width="200" Height="200">
<Canvas Background="Beige">
<Line X1="0" X2="200" Y1="100" Y2="100" Stroke="Black"/>
<Line X1="100" X2="100" Y1="0" Y2="200" Stroke="Black"/>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Margin="2">
<TextBlock.RenderTransform>
<TranslateTransform X="100" Y="100"/>
</TextBlock.RenderTransform>
hello world1
<LineBreak/>
hello world2
<LineBreak/>
hello world3
</TextBlock>
</Canvas>
</Grid>
I want the text to appear in the top-right quadrant of my Canvas instead of the bottom right quadrant.
Is it possible to do in WPF?
Currently the text is drawn from topleft to bottomright, I would like it do be drawn from bottomleft to topright.
I couldn't find an answer on the internet that works inside a Canvas.
In my production code the text should be able to be of any length and height.
Edit:
I've been asked to provide a fully working sample, so here goes:
XAML:
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<!--The drawing area can be anything, a grid, a panel, a canvas... Can't just use specific alignment tools so I have to use a Transform-->
<Grid x:Name="DrawingArea" Background="Beige" MouseMove="UIElement_OnMouseMove">
<TextBlock x:Name="TextBlock" Margin="2">
hello world1
<LineBreak/>
hello world2
<LineBreak/>
hello world3
</TextBlock>
</Grid>
</Grid>
</Window>
Code behind:
using System.Windows.Input;
using System.Windows.Media;
namespace WpfApp1
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void UIElement_OnMouseMove(object sender, MouseEventArgs e)
{
var mousePos = e.GetPosition(DrawingArea);
TextBlock.RenderTransform = new TranslateTransform(mousePos.X, mousePos.Y);
}
}
}
Currently the text appears below the default Windows mouse cursor, I'd like it to appear above the default Windows mouse cursor.
You see it in the lower right part because of the TranslateTransform. You set it to X=100, Y=100. If you set Y=0 it should be on the top.
But you should consider some things with this code:
Why use TranslateTransform inside a canvas? You can just add the Canvas.Top and Canvas.Left properties to the TextBlock and that should do it. Use the TranslateTransform only if you're looking to animate the element, and even then, it's more convenient to set it to (0, 0), and change it only during the animation.
Why are you using the canvas at all? And more over why inside a Grid? You should be able to achieve what you want by using a single Grid, or even a DockPanel. A Canvas is used only for graphics, that should always remain in the same place. There are better solutions for data, especially if it's supposed to change during runtime.
If you want a cross in the background of your grid, you can try something like this:
<Grid
Width="200"
Height="200"
Background="Beige">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Line
X1="0"
X2="200"
Y1="100"
Y2="100"
Stroke="Black"
Grid.RowSpan="2"
Grid.ColumnSpan="2"/>
<Line
X1="100"
X2="100"
Y1="0"
Y2="200"
Stroke="Black"
Grid.RowSpan="2"
Grid.ColumnSpan="2"/>
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Center" Margin="2"
Grid.Row="0"
Grid.Column="1">
hello world1
<LineBreak/>
hello world2
<LineBreak/>
hello world3
</TextBlock>
</Grid>
Add a grid to your canvas and set the properties
HorizontalAlignment="Right"
VerticalAlignment="Top"
<Canvas x:Name="newCanvas">
<Grid>
<Label Content="Hello World!"
HorizontalAlignment="Right"
VerticalAlignment="Top"
/>
</Grid>
I'm trying to resize a custom usercontrol through a thumb positioned inside the usercontrol itself.
This is the usercontrol:
<UserControl x:Class="ER.Entity"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ER"
mc:Ignorable="d"
Name="entityRoot">
<Grid Name="entityGrid">
<Thumb x:Name="resizeThumb" Height="10" Width="10" Margin="200,90,-15,-10" DragDelta="Resize" />
<Border Opacity="100" BorderThickness="5" BorderBrush="Black">
<TextBlock x:Name="textBox1" TextWrapping="Wrap" Text="{Binding ElementName=entityRoot, Path=EntityName}" VerticalAlignment="Top" PreviewMouseDown="EntityPreviewMouseDownHandler" PreviewMouseMove="EntityPreviewMouseMoveHandler" PreviewMouseUp="EntityPreviewMouseUpHandler" />
</Border>
</Grid>
And this is the method triggered by the DragDelta event:
private void Resize(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
entityGrid.SetValue(WidthProperty, entityGrid.ActualWidth + e.HorizontalChange);
entityGrid.SetValue(HeightProperty, entityGrid.ActualHeight + e.VerticalChange);
}
The problem is that, when i drag the thumb, the resizing of the usercontrol is much bigger than the mouse movement.
The problem is that because your Thumb object is referenced to the left and top of the Grid, when you change the size of the Grid that in turn causes an effective relative movement of the Thumb in addition to the movement caused by the mouse.
Changing the Thumb alignment to be Right and Bottom, and moving the Thumb positioning from the Thumb.Margin to the Grid's Width and Height properties allows the Thumb to resize the Grid as intended:
<Grid Name="entityGrid" Width="200" Height="90">
<Thumb x:Name="resizeThumb" Height="10" Width="10"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Margin="0,0,-15,-10" DragDelta="Resize" />
<Border Opacity="100" BorderThickness="2" BorderBrush="Black">
<TextBlock x:Name="textBox1" TextWrapping="Wrap"
Text="{Binding ElementName=entityRoot, Path=EntityName}"
VerticalAlignment="Top"
PreviewMouseDown="EntityPreviewMouseDownHandler"
PreviewMouseMove="EntityPreviewMouseMoveHandler"
PreviewMouseUp="EntityPreviewMouseUpHandler" />
</Border>
</Grid>
I have a project consisting of two pages. One page is having th XAML of a User control developed by me.
The another page has the logic of cropping the image that is present in the image box on that page. I want to use my control on that page and assign the border background of the user control to the image cropped .
The following code is of my UserControl XAML ! The cs file for this page has no code implementation
<UserControl
x:Class="controlMagnifier.MagnifierUsercontrol"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:controlMagnifier"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Canvas x:Name="controlCanvas" x:FieldModifier="public" Margin="112,0,108,0">
<Canvas.RenderTransform>
<RotateTransform>
</RotateTransform>
</Canvas.RenderTransform>
<Grid Height="250" Width="176" Canvas.Left="41" Canvas.Top="40" Margin="-40,0,0,0">
<Border x:FieldModifier="public" x:Name="imgBorder" Width="150" CornerRadius="50,50,50,50" Margin="13,25,13,97">
<Border.Background>
<ImageBrush x:Name="image1" ImageSource="/Assets/images.jpg" />
</Border.Background>
</Border>
<TextBlock x:Name="txtreading" Height="30" Width="80" Margin="0,-145,0,0" FontWeight="Bold" Foreground="Red" FontSize="20" Text="ABC" TextAlignment="Center" />
<!--<Image Height="120" Width="150" Margin="0,-50,0,0" Source="Assets/SmallLogo.scale-100.png" ></Image>-->
<Path x:Name="MagnifyTip" Data="M25.533,0C15.457,0,7.262,8.199,7.262,18.271c0,9.461,13.676,19.698,17.63,32.338 c0.085,0.273,0.34,0.459,0.626,0.457c0.287-0.004,0.538-0.192,0.619-0.467c3.836-12.951,17.666-22.856,17.667-32.33 C43.803,8.199,35.607,0,25.533,0z M25.533,32.131c-7.9,0-14.328-6.429-14.328-14.328c0-7.9,6.428-14.328,14.328-14.328 c7.898,0,14.327,6.428,14.327,14.328C39.86,25.702,33.431,32.131,25.533,32.131z" Fill="#FFF4F4F5" Stretch="Fill" Stroke="Black" UseLayoutRounding="False" Height="227" Width="171" />
</Grid>
</Canvas>
</UserControl>
In the user control XAML , we can see that I have set the
to a static image. I want to access this user control to another page and want to assign the element to the cropped image output on the other page. The other page MainPage.Xaml has the code for image cropping.
Any help would be appreciated