Windows Store Apps: How to draw a dashed line? - windows-8

How can I draw a dashed Line in Windows Store Apps (XAML) ?

Use the StrokeDashArray property. For example, the following XAML produces the line in the image below it:
<Line Stroke="Red" X1="0" X2="400" Y1="0" Y2="400"
StrokeThickness="9" StrokeDashArray="3,5" StrokeDashCap="Round" />

Related

Xamarin Forms custom frame shape around Image

I have an image in my app with a frame around it to make the image a circle. I want a custom shape for the Frame, but can't figure out how to get this exact shape.
(Please ignore the house inside the drawing, it is simply there to represent an Image in Xamarin, I only need the outline to be the shape).
I also don't require the Frame to have a colored border, only the shape.
Any help will be appreciated!
Here is my code right now for the Frame + Image:
<Frame x:Name="PictureFrame" Padding="0" Margin="0" HorizontalOptions="Center" BorderColor="Transparent" WidthRequest="80" HeightRequest="80" HasShadow="False">
<Image x:Name="Picture" Source="picture" Margin="0,0,0,0" Aspect="AspectFill"/>
</Frame>
You probably have to create a custom renderer to achieve what you're looking for. For example, on Android the Frame mask is actually implemented with a bezier path that you could control to your liking if you dive a bit deeper into the code.
Take a look at the FreshEssentials AdvancedFrame view which almost has what you need. The modification they've made is that you can have a sharp 90 degree angle on either both corners on the left or on the right. You'd simply have to modify this code a little bit to have a rounded corner on all except the top left corner.
What you need to modify are the following:
AdvancedFrame (In case you want the corner radiuses to be configurable separately or something else. This is the base that inherits from the original Frame control in Xamarin.Forms)
AdvancedFrameRendererDroid
AdvancedFrameRendereriOS
AdvancedFrameRendererUWP (Only if you require UWP support)
Tips:
On Android, the background mask for the frame is defined with the Path class.
On iOS, UIBezierPath class from the UIKit framework is used.
Now with Xamarin.Forms you can use Shapes. The Path Data is your circle with point.
<AbsoluteLayout
BackgroundColor="AliceBlue"
>
<Path
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
Margin="8"
Data="M142.798828,0 C221.365114,0.164668482 285,63.9009723 285,142.5 C285,221.200577 221.200577,285 142.5,285 C63.7994232,285 0,221.200577 0,142.5 C0,139.784357 0.0759637392,137.086456 0.225882227,134.408306 L0,133.828125 L0,0 L142.798828,0 Z"
Stroke="LightBlue"
StrokeThickness="2"
HorizontalOptions="Center"
VerticalOptions="Center"
/>
<Image
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
Aspect="AspectFit"
Source="brigadeiro"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="94"
HeightRequest="94"
/>
</AbsoluteLayout>

SystemAccentColor + Converter

[UWP] I created a SolidColorBrush resource from SystemAccentColor color, I tried to add a converter to lighten the color but it work only at runtime... I see the color lighter but if I go in the settings OS and I change the accent color, it change in other texts while my color with converter doesn't work. Is there a method to "update" my resource when I change the system accent color?
In my app:
<Grid Background="{ThemeResource AuraAccent}"/>
<Grid Background="{ThemeResource AuraAccentLight1}"/>
ResourceDictionary:
<SolidColorBrush x:Key="AuraAccent" Color="{ThemeResource SystemAccentColor}"/>
<SolidColorBrush x:Key="AuraAccentLight1" Color="{Binding Source={ThemeResource SystemAccentColor}, Converter={ThemeResource shade}, ConverterParameter=30}"/>
AuraAccent work in runtime and when I change the accent color.
AuraAccentLight1 work in runtime but doesn't work when I change the accent color.
How actually it work:
http://sharex.lucapatera.it/uploads/2016-08-31_19-34-32.mp4
I went through few of the resource dictionary files and noticed that The Dictionary will be loaded when App Initially Loads. The changes for Actual Theme Resource will be updated but not custom Brushes ( In your case AuraAccentLight1 because it uses a converter).
This is what I did. Instead of creating a ResourceDictionary with a Shade colour which works only once, I bound the second Grid to first grid saying when first Grid's colour change, second Grid Colour also should be updated.
So below is my XAML
<Grid x:Name="grid" Background="{ThemeResource AuraAccent}"/>
<Grid>
<Grid.Background>
<SolidColorBrush Color="{Binding Background.Color, Converter={StaticResource ColorHelper}, ElementName=grid,ConverterParameter=30}" />
</Grid.Background>
</Grid>
Let me know if this Helps.
Inspired by AVK Naidu, I have resolved in this way:
<SolidColorBrush x:Key="AuraAccentLight1" Color="{Binding Color, Source={ThemeResource AuraAccent}, Converter={ThemeResource shade}, ConverterParameter=30}"/>
Thanks to everyone
Final result:
http://sharex.lucapatera.it/uploads/2016-09-10_19-33-45.gif

{Binding ElementName=...} does not work from any CompositeTransform property

I have the following code in which I hide a WebView just under the main Grid (LayoutRoot) so I can do a sliding animation later:
<Page...>
<Grid x:Name="LayoutRoot">
...
<Grid x:Name="ContentRoot">
...
</Grid>
<WebView...>
<WebView.RenderTransform>
<CompositeTransform TranslateY="{Binding ElementName=LayoutRoot,
Path=ActualHeight}"/> <!--Does not work-->
</WebView.RenderTransform>
</WebView>
</Grid>
</Page>
When I first type the {Binding ElementName=...} line into the designer, the WebView appears just below the Grid like it should. However, when I rebuild the solution or run the app, the WebView simply obscures the whole LayoutRoot.
This will happen regardless of what I am binding to/whatever the control is; however, binding to the exact same expression will show up properly in the designer and in the phone. To demonstrate what I am saying:
<Button Width="{Binding ElementName=LayoutRoot, Path=ActualHeight}"> <!--Works perfectly, both on designer and phone-->
<Button.RenderTransform>
<CompositeTransform SomeProperty={Binding ElementName=SomeElement, Path=SomePath}"/> <!--This does not work-->
</Button.RenderTransform>
</Button>
Is there any way to bind to LayoutRoot.ActualHeight short of writing C# code for this?
One problem you have is you are trying to bind to ActualHeight which is not a dependency property nor an observable (INotifyPropertyChanged) property, so the binding is only evaluated once when it's first created.

how to allow user to move\resize an image control on a picture on Windows Phone 8

Here is the challenge I am having with a Windows 8 phone app
Flow: The user takes a photo using a Windows 8 phone. The logic uses the PhotoCamera class, which works for my purpose. Once the stream is available, I transfer the stream to a results page, where a BitmapImage is constructed from the stream. This bitmap image is then used as the source of an Image object, which is defined in the xaml file. The idea is to show the taken picture to the user for confirmation, and this flow works fine. Here is what the result page does.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
MemoryStream stream = (MemoryStream)App.ObjectNavigationData;
stream.Seek(0, SeekOrigin.Begin);
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
imgCaptureResult.Source = bitmapImage;
imgCaptureResult.Visibility = System.Windows.Visibility.Visible;
}
What I want to do is to display a rectangle where the user can define a crop area, which I can do by defining a rectangle object (or multiple lines) on the image object itself. And this works fine as long as the overlay object (crop area) is static. See the xaml below. (Note that the canvas here is the viewFinder (the camera feed), not the results page. In the results page, I will be using the image object instead of the canvas, but the concept works, I can overlay lines over another UI element, as long as the lines are static)
<Canvas x:Name="viewfinderCanvas"
Grid.Column="0"
Width="640"
Height="480"
HorizontalAlignment="Left" >
<!--Camera viewfinder -->
<Canvas.Background>
<VideoBrush x:Name="viewfinderBrush" />
</Canvas.Background>
<Line X1="20" Y1="20"
X2="100" Y2="20"
Stroke="Red"
StrokeThickness="4"/>
<Line X1="20" Y1="20"
X2="20" Y2="100"
Stroke="Red"
StrokeThickness="4"/>
<Line X1="540" Y1="20"
X2="620" Y2="20"
Stroke="Red"
StrokeThickness="4"/>
<Line X1="620" Y1="20"
X2="620" Y2="100"
Stroke="Red"
StrokeThickness="4"/>
<Line X1="540" Y1="460"
X2="620" Y2="460"
Stroke="Red"
StrokeThickness="4"/>
<Line X1="620" Y1="460"
X2="620" Y2="380"
Stroke="Red"
StrokeThickness="4"/>
<Line X1="20" Y1="460"
X2="100" Y2="460"
Stroke="Red"
StrokeThickness="4"/>
<Line X1="20" Y1="460"
X2="20" Y2="380"
Stroke="Red"
StrokeThickness="4"/>
</Canvas>
But I want the user to be able to re-size this rectangle by gestures, so that s\he can truly customize the crop area. Either move the whole rectangle up\down, or move the bottom side up\down etc. In other words, I need a control which resembles a "Select" rectangle you see in Paint.Net so that the crop area is selectable by the user. I couldn't figure out a way to do this. I looked at the Phone API as well as the Nokia Imaging SDK, but nothing lit a bulb in my head. Any suggestions are appreciated. Thanks
You could also have an approach where user could select the vertical and the horizontal boundaries separately instead of panning it (if panning is not straight forward and no control does that easily). Let the user select the vertical limit with some vertical slider, and then in the same way make him do the horizontal selection. And then you can shade the areas selected by him vertically and horizontally with apt colors to show a panning kind of effect.
This, only if you don't achieve what you are trying to.

Joint tracking image on Skeletal Tracking not following correctly

When I run the Channel9 MSDN Kinect quickstart series code for skeletal tracking, there are suppose to be images/ellipses that overlap the location of the joints selected. Instead I get images/ellipses that are slightly off and not exactly over the location of the joints. No matter where I move the joints, the images stay off to the side of the exact location of the joint. I have seen the video here (http://channel9.msdn.com/Series/KinectQuickstart/Skeletal-Tracking-Fundamentals) and theirs works. Is there something I did wrong that I am not noticing that I changed or forgot to update?
Update:
This is some line of code that might be causing it:
CoordinateMapper cm = new CoordinateMapper(kinectSensorChooser1.Kinect);
//Map a joint location to a point on the depth map
//head
DepthImagePoint headDepthPoint =
cm.MapSkeletonPointToDepthPoint(first.Joints[JointType.Head].Position, depth.Format);
This is a change over what is in the video as they updated with a new method to map skeleton to depth and depth to color point. It eliminates an error that occurred when the stream was terminated.
The method has parameters that ask for position and format. Could it be that the depth.Format is not the same format as the RGB640x480Resolution?
//Map a depth point to a point on the color image
//head
ColorImagePoint headColorPoint =
cm.MapDepthPointToColorPoint(depth.Format, headDepthPoint,
ColorImageFormat.RgbResolution640x480Fps30);
On the main window screen this is what I have for creating the images i am using:
<Canvas Name="MainCanvas">
<my:KinectColorViewer Canvas.Left="50" Canvas.Top="50" Height="480" Name="kinectColorViewer1" Width="640"
Kinect="{Binding ElementName=kinectSensorChooser1, Path=Kinect}" />
<Ellipse Canvas.Left="0" Canvas.Top="0" Height="50" Name="leftEllipse" Width="50" Fill="#FF4D298D" Opacity="1" Stroke="White"></Ellipse>
<Ellipse Canvas.Left="100" Canvas.Top="0" Height="50" Name="rightEllipse" Stroke="White" Width="50" Fill="#FF2CACE3" Opacity="1" />
<my:KinectSensorChooser Canvas.Left="250" Canvas.Top="380" Name="kinectSensorChooser1" Width="328" />
<Ellipse Canvas.Left="225" Canvas.Top="84" Height="50" Name="headImage" Stroke="White" Width="50" Fill="#FF2CACE3" Opacity="1" />
<my:KinectSkeletonViewer Canvas.Left="646" Canvas.Top="240" Name="kinectSkeletonViewer1" Width="640" Height="480" Kinect="{Binding ElementName=kinectSensorChooser1, Path=Kinect}" />
</Canvas>
And I have commented these lines of code about scaling position
//ScalePosition(headImage, first.Joints[JointType.Head]);
// ScalePosition(leftEllipse, first.Joints[JointType.HandLeft]);
//ScalePosition(rightEllipse, first.Joints[JointType.HandRight]);
and this function has been commented.
private void ScalePosition(FrameworkElement element, Joint joint)
{
//convert the value to X/Y
//Joint scaledJoint = joint.ScaleTo(1280, 720);
//convert & scale (.3 = means 1/3 of joint distance)
// Joint scaledJoint = joint.ScaleTo(1280, 720, .3f, .3f);
// Canvas.SetLeft(element, scaledJoint.Position.X);
// Canvas.SetTop(element, scaledJoint.Position.Y);
}
and this is commented out so no transform parameters are used:
//sensor.SkeletonStream.Enable(parameters);
and this is what stream and skeleton enable lines of code look like:
sensor.SkeletonStream.Enable();
sensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(sensor_AllFramesReady);
sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
Try the following steps.
Comment the lines that scaleTo() for testing porposes.
You initialized kinect with 640x480? Try to put this sizes to your my:KinectSkeletonViewer element on the XAML. I see that actualy it is Width="320" Height="240", change it.
Also check to not use strech on your Image element or in the Canvas that hosts it, for security, delete the Height="Auto" and Width="Auto" from your MainCanvas.
Start your skeleton stream with no TransformSmoothParameter or, if you want to use this, try the following parameters
this.KinectSensorManager.TransformSmoothParameters = new TransformSmoothParameters
{
Smoothing = 0.5f,
Correction = 0.5f,
Prediction = 0.5f,
JitterRadius = 0.05f,
MaxDeviationRadius = 0.04f
};
I am do the same you are trying to do using kinect for xbox and it worked fine to me.
When the channel9 video was recorded the sdk did not have the CoordinateMapper class, so, you dont need to convert to depth then to color, the coordinate mapper has a method to directly map the skeleton point to the color point, the method is MapSkeletonPointToColorPoint(), use the method and dont worry about the Depth Data.
It looks the problem I had was in the xaml code. I replaced the xaml code I had and replaced it with the original xaml code for the images and objects on my canvas.
<my:KinectColorViewer Canvas.Left="0" Canvas.Top="0" Width="640" Height="480" Name="kinectColorViewer1"
Kinect="{Binding ElementName=kinectSensorChooser1, Path=Kinect}" />
<Ellipse Canvas.Left="0" Canvas.Top="0" Height="50" Name="leftEllipse" Width="50" Fill="#FF4D298D" Opacity="1" Stroke="White" />
<Ellipse Canvas.Left="100" Canvas.Top="0" Fill="#FF2CACE3" Height="50" Name="rightEllipse" Width="50" Opacity="1" Stroke="White" />
<my:KinectSensorChooser Canvas.Left="250" Canvas.Top="380" Name="kinectSensorChooser1" Width="328" />
<Image Canvas.Left="66" Canvas.Top="90" Height="87" Name="headImage" Stretch="Fill" Width="84" Source="/SkeletalTracking;component/c4f-color.png" />
It might been have been a property or event setting that I had set incorrectly or not at all that introduced a shift in the image objects.