How to find out size of an Canvas that created in xaml file?
for example I create an Canvas by
<Page
x:Class="MyApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Canvas x:Name="canvas" Background="White">
</Canvas>
</Page>
and full screen is white or whatever color I specified for that canvas
than in my class I tried but with no luck
double h = canvas.Height; // NaN
h = canvas.ActualHeight; // 0
so how do I found out the actual size of that canvas? or the size is 0 but than how to make the canvas full screen size?
I am new C# and metro developer and so confused how everything works compare to iOS.
Where in your code are you checking the size of the Canvas? I'm assuming you're doing it in the page constructor or somewhere else that is running before the UI layout has run. In this case, all auto sized elements (NaN height or width) still have their default size. If you check the size after layout has completed, like in a Loaded event handler in your page, then you should see the true rendered size.
If your Canvas happens to only contain one Image, you can use:
var Width = ((Image) (MyCanvas.Children[0])).Width;
var Height = ((Image) (MyCanvas.Children[0])).Height;
Of course, you can switch out the two Image casts for another element, if your Canvas contains one of some other item.
Alternatively just give the wrapped Image (or other element) a name, and reference it as MyImage.Width.
Related
I've tried to load some SVG files with the same result: they're rendering clipped and they seem to ignore the layout.
For instance:
<UserControl
x:Class="SuppaFlight.UWP.AnglesControl"
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"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="1000">
<Image Source="Assets/treeicon.svg" Stretch="UniformToFill" />
</UserControl>
Renders like this, ignoring the Stretch setting:
What's going on there? Is it a known problem? How to workaround this?
Open the svg image in the editor
delete the width and height properties.
add viewbox="0 0 15 15". 15 is the value of the deleted width and height.
add width and height properties to image tag in xaml as desired.
these steps solved my issue, may be will help you
Try to convert your SVG image into PNG or some other format online
Website to Convert SVG to PNG
The following code throws a cryptic System.ArgumentException from the RenderAsync method "Value does not fall within the expected range." If on the other hand my Canvas is part of a visible XAML tree it works. Is it impossible to render some XAML that isn't displayed on screen?
Canvas c = new Canvas();
c.Width = 40;
c.Height = 40;
c.Background = new SolidColorBrush(Color.FromArgb(0xff, 0x80, 0xff, 0x80));
RenderTargetBitmap x = new RenderTargetBitmap();
await x.RenderAsync(c);
I almost thought this answer would work, but no luck, I guess it only applies to WPF: Create WPF element offscreen and render to bitmap
UPDATE:
So far my best idea is to put the Canvas I want to render to into the currently visible page but place it beneath what is normally the root UIElement that fills the screen so it isn't visible to the user:
<Grid>
<Canvas x:Name="HiddenCanvas"/>
<Grid x:Name="mainElement" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
</Grid>
</Grid>
It isn't beautiful but it seems to work. Lets see if anyone can do better
satur9nine's solution to put the rendered UI tree somewhere behind an opaque foreground seems to be the only supported solution. You could also fiddle with the opacity of the parent element to avoid having it showing up. Another option is to render it yourself with Direct2D or use something like the WinRTXamlToolkit.Composition.Render() methods from WinRT XAML Toolkit.
WinRTXamlToolkit.Composition namespace has this extension that works. Just call this method:
await WriteableBitmapRenderExtensions.RenderToPngStream(element);
Correct me if I'm wrong, but I believe that if I draw a line in WPF and it is small enough, then the line will be aliased out. Also if a line is not drawn on a pixel then it may become dimmer. I assume that if a line is < 1 pixel wide it will also be dimmed by averaging the colors that are in that spot.
My goal is to draw a graph of a bunch of signals without having the lines I draw disappear or become dimmed to the point the user might not notice them.
Questions: if I draw a line with a width of 1 device independent pixels, is it guaranteed to be at least one pixel wide? if not, is there any way to ensure that a line is at least one pixel wide?
You have to speficy
SnapsToDevicePixels="True"
in the header of your XAML
ex:
<Window
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"
SnapsToDevicePixels="True">
You can see the way it changes the line in this link
It seems that I am unable to set the Height Property of a Window element to 0. Is there an explanation for that?
This code does not works, nor does forcing Height to 0 in Code behind works. ActualHeight always returns 14.0 for my machine
<Window x:Class="AnimWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="0" Width="525" AllowsTransparency="True" WindowStyle="None" Background="YellowGreen" >
</Window>
Hint appreciated.
Edit: Sorry, forgot an explanation :) I would like to create some sort of notification popup window like outlook does to notify user of something. While opacity works well, animating or setting height to 0 does not.
Since you have no borders, just Hide and Show the window instead of setting it's Height to zero or a positive value.
Well, I spent a little research. First, this code:
<Window x:Class="ZeroHwindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="0" Width="525"
WindowStyle="None"
AllowsTransparency="True"
Background="Yellow" />
Returns the value of the height of 6, because you have 14. I run this code on Windows XP, I suspect that you have a different OS. Next I set the parameter ResizeMode in NoResize, and got the height 2.
If you set ResizeMode="CanResizeWithGrip", we get as much as 17 pixels, which would fit the Grip. We see therefore that the system itself inserts standard elements, even when the parameters are: WindowStyle="None", AllowsTransparency="True".
I also tried to set the parameters: ShowInTaskbar = False, ShowActivated = False, no avail, the window was not visible, but the height was 2 (it turns out that some people believe nothing to these parameters, in fact, height / width is not zero).
By the way, I forgot to mention: I showed all the values in the
ContentRendered="Window_ContentRendered"
like that:
private void Window_ContentRendered(object sender, EventArgs e)
{
MessageBox.Show(this.Height.ToString());
MessageBox.Show(this.ActualHeight.ToString());
}
Just trying to set the SizeToContent = WidthAndHeight: the same height - 2, but the Window is not visible.
The only thing that somehow helped, it:
private void Window_ContentRendered(object sender, EventArgs e)
{
this.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
this.Arrange(new Rect(0, 0, 0, 0));
MessageBox.Show(this.Height.ToString());
MessageBox.Show(this.ActualHeight.ToString());
}
In thic case, ActualHeight return 0.
Perhaps a standard element is drawn, and it is impossible to get 0. I also tried to set Styles / Templates, but the height was not set to zero. In principle, as expected, for sure it is set at the system level.
Still decided to look at it through the Snoop.
Part #1. Standard state
You can see that the local value is set high.
Part #2. Using Arrange and Measure
Some links:
UIElement.Arrange
UIElement.Measure
I have a grid inside a canvas on a tab.
The grid contains a large bitmap image,
I have(tried to) bound the size of the grid to the size of the tab and also have a five pixel margin around the grid.
imageTab.cs
public ImageTab(SendInfo sendInfo, int numImge, int numAccs)
{
imageDisplay = new ImageDisplay(sendInfo, numImge, numAccs);
imageDisplay.ClipToBounds = true;
CreateCanvas();
}
private void CreateCanvas()
{
Canvas canvas = new Canvas();
canvas.Children.Add(imageDisplay);
this.AddChild(canvas);
}
ImageDisplay.xaml
<UserControl x:Class="MyProj.ImageDisplay">
<Grid Margin="5,5,5,5" Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=TabControl, AncestorLevel=1}, Path=ActualHeight}">
<Image/>
</Grid>
</UserControl>
The grid comes off the bottom of the tab area slightly causing the bottom of the image to be cut off.
Is there a problem with my databinding, do I need to apply some sort of offset to it? (size of tab - 10pixels for the margin?)
You don't need to set the Height property at all (also realize that it is incorrect to do so as you have it when you consider the 5 pixel margin, i.e., it would be off by 10 pixels).
Just leave VerticalAlignment and HorizontalAlignment at their default values (which is Stretch) to get the effect you are after here.
Try this on a new Window to see what I mean:
<Window x:Class="WpfApplication9.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="438" Width="587" Background="Pink">
<Grid Background="Black" Margin="5">
</Grid>
</Window>
The grid here will be black and will always stretch to the size of the window, using a 5 pixel margin which you will see because the Window's back color is pink.