I'm currently migrating a project from Windows Phone 8.1 to UWP, and I'm having problems with a XAML line that doesn't rotate when renderTransform compositeTransform rotation in code, but happens in if change is made in XAML. In Windows Phone 8.1 it worked without any problem.
Here's XAML part:
<Maps:MapControl
<Line x:Name="mapLineMilestoneHelper"
Stroke="Black" StrokeThickness="2" Opacity="1.0" StrokeDashArray="2,2"
RenderTransformOrigin="0.5, 0.5"
X1="0" Y1="-1000" X2="0" Y2="1000" Visibility="Collapsed">
<Line.RenderTransform>
<CompositeTransform x:Name="lineMilestoneHelperAzimuth" Rotation="90.0"/>
<!--<RotateTransform x:Name="lineMilestoneHelperAzimuth"
CenterX="0.5" CenterY="0.5" Angle="0"/>-->
</Line.RenderTransform>
</Line>
</Maps:MapControl
This line is drawn inside a Map Control. And then changed in code (but veen I change Rotation value to 0 it doesn't rotate.
Here's the C# code that should rotate the XAML line above:
lineMilestoneHelperAzimuth.Rotation = azimuth;
As you have seen, I've tried with RotateTransform also, but it didn't work.
Any idea why it happens?
Thank you
According to https://learn.microsoft.com/en-us/windows/uwp/maps-and-location/display-poi#add-a-line you can add lines to a map from code.
I assume that this is because that way you can specify the locations of the elements by their location on the map (perhaps in geo coordinates) so they move with the map when panning and zooming the map.
Another approach, if you are looking for an overlay kind of setup (like a Heads Up Display): nest the map in a Grid and put the line as a sibling to the map in the grid:
I made a minimal working example. Notice the changed line coordinates and setting Visibility to Visible instead of Collapsed to bring the line into view and make it visible. I also used a hard-coded brush and line thickness.
<Page xmlns:my="using:Windows.UI.Xaml.Controls.Maps"
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<my:MapControl/>
<Line x:Name="mapLineMilestoneHelper"
Stroke="Aqua"
StrokeThickness="5"
Opacity="1.0"
StrokeDashArray="2,2"
RenderTransformOrigin="0.5, 0.5"
X1="0"
Y1="0"
X2="700"
Y2="500"
Visibility="Visible">
<Line.RenderTransform>
<CompositeTransform x:Name="lineMilestoneHelperAzimuth"
Rotation="90.0" />
<!--<RotateTransform x:Name="lineMilestoneHelperAzimuth" CenterX="0.5" CenterY="0.5" Angle="0" />-->
</Line.RenderTransform>
</Line>
<Button Content="Button"
HorizontalAlignment="Left"
Margin="64,80,0,0"
VerticalAlignment="Top"
Click="Button_Click" />
</Grid>
</Page>
And in code-behind:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
lineMilestoneHelperAzimuth.Rotation = 45;
}
}
If you want to draw a line on the map in geographic coordinates that moves with the map, it's recommended to use a MapPolyine rather than XAML
https://learn.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.Maps.MapPolyline
It will perform better and stick to the map beter (XAML tends to drift relative to the map).
Related
In my WPF program, I want to draw a shape. Then after I press a button, the program plays a video in fullscreen mode. I can't seem to make the video play in fullscreen on the canvas.
my XAML is like below
<Canvas>
<Ellipse Name="face1" Panel.ZIndex="2" Fill="Green" Width="400" Height="400" />
<MediaElement Panel.ZIndex="1000" Name="videoControl1" Stretch="Fill"
Source="C:\Users\videos\carcrash.mp4"
LoadedBehavior="Manual" MediaEnded="videoControl1_MediaEnded">
</MediaElement>
</Canvas>
As you can see, I put the video in front of my shape. as sson as a button is pressed, I then start to play the video. So the video will be in front of the shape. The problem is that the video is very small. How to make it full screen?
Per Dennis Cheng's comment here:
Canvas is a "no-layout" panel so children won't size to parent. Try
Grid if you want children fill or manually Bind to the parent's size
if you must use a Canvas:
<Canvas x:Name="MyCanvas"
Width="300"
Height="300">
<Ellipse Name="face1"
Width="400"
Height="400"
Panel.ZIndex="2"
Fill="Green" />
<MediaElement Name="videoControl1"
Width="{Binding RelativeSource={RelativeSource Self},
Path=Parent.ActualWidth}"
Height="{Binding RelativeSource={RelativeSource Self},
Path=Parent.ActualHeight}"
Panel.ZIndex="1000"
Source="C:\Users\videos\carcrash.mp4" />
</Canvas>
That scales the video's width to that of the containing Canvas, but it remains in proportion to its original dimensions.
If you use a Grid you can achieve the kind of scaling you're aiming for:
<Grid Width="500" Height="500">
<Ellipse Name="face1"
Width="400"
Height="400"
Panel.ZIndex="2"
Fill="Green" />
<MediaElement Name="videoControl1"
Grid.Row="0"
Panel.ZIndex="1000"
Source="D:\Downloads\The.Strain.S01E13.HDTV.x264-LOL.mp4"
Stretch="Fill" />
</Grid>
I use a Path element(StrokeThickness="1" SnapsToDevicePixels="True")
in Grid. I want to resize the window, the Grid element is wrapped by a Viewbox element.
Problem
When I resize the window, the Path will disappear some time. If I turn SnapsToDevicePixels to false, the Path element may blur which is not what I want.
How to avoid a single pixel line dispear?
the XAML code:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="207" Width="475">
<Viewbox Stretch="Fill">
<Grid Height="320" Width="517">
<Path Data="M0,0 H1 z" StrokeThickness="1" Stroke="Black" Margin="72,73,79,218" Stretch="Fill" SnapsToDevicePixels="True" MinHeight="1"/>
</Grid>
</Viewbox>
Pity for I have no reputation to post the runtime effect.
I have experimented the same problem with separators put in a Viewbox. Some of these disappear for some resolutions. To fix it, I replace them with border with 1 pixel height :
< Border Background="DarkGray" Grid.Row="0" Grid.ColumnSpan="7" Height="1" />
This avoid single line of one pixel to disappear in viewBox.
Hope it could be useful for you too.
I'm working with camera on wp8. Now I want to achieve effect like in Nokia City Lens app. I want to add additional layer with POI tags on real time working camera's window. Have you any tips how to work with it? It's any library or something to draw tags on PhotoCamera's window? I totally don't know how to start...
If you're using a <Canvas> with <VideoBrush> then you can add as many layers as you like. For example:
<!-- This will draw a Red Rectangle # 50, 50 over the camera output -->
<Grid x:Name="ContentPanel" Margin="12,0,12,0">
<Canvas x:Name="cam_canvas" Width="480" Height="480" Margin="-12,0">
<Canvas.Background>
<VideoBrush x:Name="cam_video_brush" Stretch="None">
<VideoBrush.RelativeTransform>
<CompositeTransform Rotation="90" CenterX="0.5" CenterY="0.5" />
</VideoBrush.RelativeTransform>
</VideoBrush>
</Canvas.Background>
<!-- draw rect -->
<Rectangle Canvas.Top="50" Canvas.Left="50" Canvas.ZIndex="1" Width="100" Height="100" Fill="Red"></Rectangle>
</Canvas>
</Grid>
Pay attention to Canvas.Top (Y position), Canvas.Left (X Position), Canvas.ZIndex (Layer number above the background video brush)
I'm trying to position a rectangle in the center of a grid with a restricted height, like so:
<Grid ClipToBounds="False">
<Grid Background="LightBlue" Height="10" ClipToBounds="False" Margin="0,27,0,79">
<Rectangle Height="40" Width="20" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center" ClipToBounds="False"/>
</Grid>
</Grid>
I've expected it to look like that:
But instead it looks like that:
I know the my child rectangle is bigger and it is understandable that it clips, however, my ClipToBounds have no effect of anything. After reading around, I found that indeed Grid does not respect "ClipToBounds".
I tried to use Canvas, as suggested in the aforementioned article by Dr.Wpf but I can't seem to get it right.
Is there anything I can do to make it look like the 1st picture, without resorting to C# code?
Thanks!
It's a little hard to tell exactly what your requirements are here. You said you tried it witha Canvas, but you can't seem to get it right. What didn't work?
I used this code:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="TestApp.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="175" Height="170" Background="LightGray">
<Grid>
<Canvas Background="LightBlue" Height="10"
Margin="0,27,0,79" VerticalAlignment="Top">
<Rectangle Height="40" Width="20" Fill="Black"
Canvas.Left="66" Canvas.Top="-15" />
</Canvas>
</Grid>
</Window>
and was able to essentially fake what your screenshot looked like. But (as you can tell by the Canvas.Left and Canvas.Top parts of my code) it is sort of hackish. You could get rid of the Canvas.Left by binding to the ActualWidth of the Canvas and using an IValueConverter that converts it to the correct value.
Edit:
After a little further exploration, I came up with a slightly less hackish way of doing it. Though the nesting kind of makes me cringe, the only thing hardcoded is the top margin to get it centered vertically. Again, that can be done with an IValueConverter, but you don't want that. I'm not sure I can get any better than this, unfortunately.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication10.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<Grid Background="LightBlue" Height="10" ClipToBounds="False" Margin="0,27,0,79">
<Canvas>
<Grid Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType=Canvas}}"
Height="{Binding ActualHeight, RelativeSource={RelativeSource FindAncestor, AncestorType=Canvas}}">
<Canvas HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0 -40 0 0">
<Rectangle Height="40" Width="20" Fill="Black" ClipToBounds="False"/>
</Canvas>
</Grid>
</Canvas>
</Grid>
</Grid>
</Window>
I want to view a fullscreen video and thought this works like this:
<Window x:Class="test.Overlay"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Overlay" Height="300" Width="300" WindowState="Maximized">
<Grid>
<Canvas Name="lightCanvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<MediaElement Name="lightMovie" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Source="C:\knoblauch\lights\1.wmv" Stretch="Fill" />
</Canvas>
</Grid>
but for some reason the video, in this case 1.wmv, doesnt fill up the screen.
Why?
Elements added to a Canvas will not be sized relative to the Canvas. They will be their non stretched size or a size which has been explicitly set (through setting Width, Height, etc). To get items to stretch you need containers that support that functionality suach as a Grid.
For instance:
<Grid>
<MediaElement Name="lightMovie" Source="C:\knoblauch\lights\1.wmv" Stretch="Fill" />
</Grid>
works as you are expecting.