Uwp more deep shadow effect for text or textblock - c#

I am trying to make more deep black shadow effect to make readable text , infront white background .
I am using this code
c# void method of loaded
var compositor = ElementCompositionPreview.GetElementVisual(this.grid).Compositor;
var brush = compositor.CreateColorBrush(Colors.Black);
var spriteVisual = compositor.CreateSpriteVisual();
spriteVisual.Size = this.grid.RenderSize.ToVector2();
var dropshadow = compositor.CreateDropShadow();
dropshadow.Mask = txtBlock.GetAlphaMask();
dropshadow.Color = brush.Color;
dropshadow.BlurRadius = 9.5f;
dropshadow.Opacity = 1.9f;
spriteVisual.Shadow = dropshadow;
ElementCompositionPreview.SetElementChildVisual(this.grid, spriteVisual);
xaml
<Grid Background="White">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid Loaded="grid_Loaded"
x:Name="grid" />
<TextBlock IsTextSelectionEnabled="True"
x:Name="txtBlock"
Text="Drop Shadow"
Foreground="White" Style="{StaticResource BodyTextBlockStyle}"
HorizontalAlignment="Center"
VerticalAlignment="Center" ></TextBlock>
</Grid>
</Grid>
Result
[![Result image][1]][1]
My Problem it is not enough black color shadow effect or opacity to watch the text .
Result
http://i.imgur.com/d6FglQT.png
I am trying to make that black effect more deep,
My Target to make shadow effect like this
Target
http://i.imgur.com/bOiRnCS.png

Related

WPF Rectangle Label Blurry

I'm using the code below to draw text over a rectangle in a WPF canvas but it seems to stretch/squash the text and sometimes the back colour does not fill the entire box.
I'm looking for a way to make sure the box is always filled and the text is clear. Probably some form of dynamic font sizing?
Thanks.
Rectangle elip = new Rectangle();
elip.Height = 6;
elip.Width = 6;
Brush brush = new SolidColorBrush(Color.FromRgb(n.Value.R,
n.Value.G, n.Value.B));
Label TB = new Label();
TB.HorizontalAlignment = HorizontalAlignment.Stretch;
TB.Margin = new Thickness(0, 0, 0, 0);
TB.Background = brush;
TB.FontSize = 12;
TB.HorizontalContentAlignment = HorizontalAlignment.Center;
TB.Content = n.Value.Stations[0].TrackId;
BitmapCacheBrush bcb = new BitmapCacheBrush(TB);
elip.Fill = bcb;
elip.Stroke = Brushes.Black;
elip.StrokeThickness = 0.5;
elip.MouseDown += ElipOnMouseDown;
Canvas.SetTop(elip, n.Value.Y - elip.Width / 2);
Canvas.SetLeft(elip, n.Value.X - elip.Height / 2);
cMain.Children.Add(elip);
You can stretch the text using a viewbox.
I recommend using a usercontrol to encapsulate all your markup for things like this. You would have to have many thousands of these things before the overhead of a usercontrol vs building rectangles and whatnot would be significant.
I built this usercontrol:
Height="18" Width="24">
<Border BorderBrush="Black"
BorderThickness="1"
Background="Magenta"
>
<Viewbox Stretch="Uniform">
<TextBlock Text="{Binding Tag, RelativeSource={RelativeSource AncestorType=UserControl}}"
TextAlignment="Center"
Margin="2"
/>
</Viewbox>
</Border>
</UserControl>
Might not be precisely what you want in terms of width, height or whatever.
You could instantiate one of these, set it's Tag, canvas top and left and add it to the canvas.
Here's the equivalent markup I used to prove it:
Title="MainWindow" >
<Grid>
<Canvas>
<local:StationView Canvas.Left="20"
Canvas.Top="100"
Tag="16B"/>
</Canvas>
</Grid>
</Window>

Change the parent of a WPF element after a rotation (setting new coordinates issue)

I need to change the parent of elements. (for group/ungroup shapes)
But I cant set the new position for an element if it has a rotation.
I saw this ,this , this and this pages and many other ways, but none worked correctly.
Please see my sample project and the following image:
The parent of Rect1 is ChildCanvas1 and The parent of Rect2 is ChildCanvas2, I want to move the Rect1 and Rect2 to the MainCanvas. (and remove the ChildCanvas and ChildCanvas2)
I don't have any problem to do that for the Rect1 because it has not any rotation.
But the Rect2 has a rotation (-20 degree) and I cant set the new coordinates for it correctly.
Please see this image:
How to change the parent of an element after a rotation and setting new coordinates correctly?
UPDATE:
Note I need a general way (for the group/ungroup elements in a big app that each element (maybe) has TranslateTransform and SkewTransform and RotateTransform and ScaleTransform)
XAML:
<Canvas x:Name="MainCanvas">
<Canvas x:Name="ChildCanvas1" Width="500" Height="250" Background="Bisque" Canvas.Top="54">
<Rectangle x:Name="Rect1" Width="200" Height="100" Fill="Red" Canvas.Left="150" Canvas.Top="100"/>
</Canvas>
<Canvas Name="ChildCanvas2" Width="500" Height="250" Background="Bisque" Canvas.Left="516" Canvas.Top="54">
<Rectangle Name="Rect2" Width="200" Height="100" Fill="Red" Canvas.Left="150" Canvas.Top="100">
<Rectangle.RenderTransform>
<TransformGroup>
<SkewTransform AngleX="-40"/>
<RotateTransform Angle="-20"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
<Button Name="btn1" Click="btn1_Click" Content="Move Rect1 to MainCanvas and Remove ChildCanvas1" Width="356" Height="30" Canvas.Left="59" Canvas.Top="310"/>
<Button Name="btn2" Click="btn2_Click" Content="Move Rect2 to MainCanvas and Remove ChildCanvas2" Width="350" Height="30" Canvas.Left="590" Canvas.Top="310"/>
C# code :
GeneralTransform transform = Rect2.TransformToVisual(MainCanvas);
Rect rect = transform.TransformBounds(new Rect(0, 0, Rect2.Width, Rect2.Height));
double ChildCanvas2Left = Canvas.GetLeft(ChildCanvas2);
double ChildCanvas2Top = Canvas.GetLeft(ChildCanvas2);
ChildCanvas2.Children.Remove(Rect2);
MainCanvas.Children.Add(Rect2);
Canvas.SetLeft(Rect2, rect.Left);
Canvas.SetTop(Rect2, rect.Top);
MainCanvas.Children.Remove(ChildCanvas2);
You need to recalculate the Rect2 after moving the Rect2 to the MainCanvas. Like this:
Canvas.SetTop(Rect2, Canvas.GetTop(Rect2) + Canvas.GetTop(ChildCanvas2));
The complete code:
private void btn2_Click(object sender, RoutedEventArgs e)
{
GeneralTransform transform = Rect2.TransformToVisual(MainCanvas);
Rect rect = transform.TransformBounds(new Rect(0, 0, Rect2.Width, Rect2.Height));
ChildCanvas2.Children.Remove(Rect2);
MainCanvas.Children.Remove(ChildCanvas2);
Canvas.SetLeft(Rect2, rect.Left);
Canvas.SetTop(Rect2, Canvas.GetTop(Rect2) + Canvas.GetTop(ChildCanvas2));
MainCanvas.Children.Add(Rect2);
}
However Rect2.TransformToVisual and transform.TransformBounds are not necessary in your case and you can do it more cleaner and easier without them and get same result. Like this:
ChildCanvas2.Children.Remove(Rect2);
MainCanvas.Children.Remove(ChildCanvas2);
Canvas.SetLeft(Rect2, Canvas.GetLeft(Rect2) + Canvas.GetLeft(ChildCanvas2));
Canvas.SetTop(Rect2, Canvas.GetTop(Rect2) + Canvas.GetTop(ChildCanvas2));
MainCanvas.Children.Add(Rect2);
EDIT: A general way:
ChildCanvas2.Children.Remove(Rect2);
MainCanvas.Children.Remove(ChildCanvas2);
Canvas.SetLeft(Rect2, Canvas.GetLeft(Rect2) + Canvas.GetLeft(ChildCanvas2));
Canvas.SetTop(Rect2, Canvas.GetTop(Rect2) + Canvas.GetTop(ChildCanvas2));
Canvas.SetRight(Rect2, Canvas.GetRight(Rect2) + Canvas.GetRight(ChildCanvas2));
Canvas.SetBottom(Rect2, Canvas.GetBottom(Rect2) + Canvas.GetBottom(ChildCanvas2));
MainCanvas.Children.Add(Rect2);
I have changed RenderTransform to LayoutTransform of Rect2:
<Rectangle Name="Rect2" Width="200" Height="100" Fill="Red" Canvas.Left="150" Canvas.Top="100">
<Rectangle.LayoutTransform>
<RotateTransform Angle="-20"/>
</Rectangle.LayoutTransform>
</Rectangle>
Now Rect2 looks like below:
When I press the second button I see this result:
So, Rect2 stays at the original position.

Drawing Lines in ItemsControl in WPF offsets new drawn Lines

I have a problem when I'm trying to draw a line with the MVVM-Pattern in WPF.
I followed this example: Drawing line on a canvas in WPF MVVM doesn't work
The Problem I have, is that I want to draw lines on a video control that is already implemented, which I can't use as ItemsPanelTemplate.
So my code currently looks like this:
xaml
<ContentControl>
<views:ExtendedMediaElement x:Name="MediaPlayer" Grid.Row="0" ScrubbingEnabled="True" LoadedBehavior="Manual" UnloadedBehavior="Stop"
MediaLength="{Binding MediaLength, Mode=OneWayToSource}"
MediaPosition="{Binding MediaPosition, Mode=TwoWay}"
EndPosition="{Binding EndPosition, Mode=OneWay}"/>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<cal:ActionMessage MethodName="MouseDown">
<cal:Parameter Value="$eventArgs"/>
<cal:Parameter Value="{Binding ElementName=ItemControl}"/>
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</ContentControl>
<ItemsControl x:Name="ItemControl" ItemsSource="{Binding Path=Lines}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line X1="{Binding X1}" Y1="{Binding Y1}" X2="{Binding X2}" Y2="{Binding Y2}" Stroke="{Binding Stroke}" StrokeThickness="{Binding StrokeThickness}"></Line>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ViewModel
private ObservableCollection<Line> _lines;
public ObservableCollection<Line> Lines
{
get { return _lines; }
set
{
if (_lines != value)
{
_lines = value;
NotifyOfPropertyChange("Lines");
}
}
}
public void MouseDown(MouseButtonEventArgs e, System.Windows.Controls.ItemsControl lineArea)
{
System.Windows.Point p = e.GetPosition(lineArea);
if (!isFirstPointSet)
{
firstClickPoint = p;
isFirstPointSet = true;
return;
}
Line l = new Line();
l.X1 = firstClickPoint.X;
l.Y1 = firstClickPoint.Y;
l.X2 = p.X;
l.Y2 = p.Y;
l.Stroke = System.Windows.Media.Brushes.Black;
l.StrokeThickness = 4;
Lines.Add(l);
firstClickPoint = p;
}
Now the first line I draw is always perfectly placed on the Click-Coordinates, but the second line has an offset on the X-Coordinate. The thrid line is often not even visible any more.
Thanks in advance for your help!
Niko
Take a look at the below example, each item in an ItemsControl are at different position. If the first line is drawn on canvas 32, the second line will be drawn on canvas 33. They are not drawn on the same, big canvas as you might expected.
You need to set the ItemsPanel property just like the answer in the link you provided.

Zooming into all content of a Canvas

I have this Xaml:
<Grid x:Name="DrawingGrid" Visibility="Collapsed">
<AppBarButton x:Name="ExitDrawingButton" Icon="Cancel" Click="ExitDrawingButton_Click"></AppBarButton>
<ScrollViewer x:Name="DScrollViewer" ManipulationMode="All" MaxZoomFactor="2.0" MinZoomFactor="1.0" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" DoubleTapped="DScrollViewer_DoubleTapped" Width="1140" Height="770">
<Canvas x:Name="inkCanvas" Background="Transparent" Width="1140" Height="770">
<StackPanel x:Name="DStackPanel" Orientation="Horizontal" Margin="0,0,0,0">
<Image x:Name="DImage0" HorizontalAlignment="Left" Source="{Binding nextImage}" Width="570" Canvas.ZIndex="0"/>
<Image x:Name="DImage1" HorizontalAlignment="Left" Source="{Binding nextImage}" Width="570" Canvas.ZIndex="0"/>
</StackPanel>
</Canvas>
</ScrollViewer>
</Grid>
I am drawing on Canvas using the CanvasManager.cs class and it is working fine.
Now I need to zoom on the Canvas: Zoom the Canvas (the ink) and Zoom what it contains (the StackPanel + the Images) together.
On doubleTapping the ScrollViewer containing the Canvas I have this method:
private async void DScrollViewer_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
Point point = e.GetPosition(DScrollViewer);
if (DScrollViewer.ZoomFactor == 1)
{
await Task.Delay(300);
DScrollViewer.ChangeView(point.X, point.Y, 2.0F, false);
}
else
{
await Task.Delay(300);
DScrollViewer.ChangeView(point.X, point.Y, 1.0F, false);
}
}
The result is: only the Canvas (its Ink) is Zooming and the StackPanel and its Images are left at the place, same scale, intact!
What Am I doing wrong?
Your mistake is you are assign a constant value for the width of each image (Width="570") so that it will never zoomed in or out unless you have change it's width programmatically.
The best way to change the image's width is bind a variable value for it, you can create a converter that divide the width of canvas over two (canvas.width / 2) and bind the width of each image to this converter..
Then your zoom will work perfectly.

How to get Zoom value in scroll viewer in C# wpf Kinect SDK 2.0?

I have recently started using the Kinect SDK 2.0 and am focusing on a zoom and pan functionality, as in the Control Basics-WPF sample.
I have got the zoom and pan functionality up and running. The problem is that I wish to access the value of the amount of zoom which has been performed by the Pinch zoom gesture.
Here is my xaml:
<UserControl x:Class="ImageNav.NavigationImage"
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:k="http://schemas.microsoft.com/kinect/2014"
mc:Ignorable="d"
d:DesignWidth="1200"
d:DesignHeight="700"
>
<Grid Grid.RowSpan="2">
<ScrollViewer Name="scrollViewer" Grid.Row="0"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
k:KinectRegion.IsHorizontalRailEnabled="true" k:KinectRegion.IsVerticalRailEnabled="true"
k:KinectRegion.ZoomMode="Enabled">
<Image Name="navigationImage" RenderTransformOrigin="0.5, 0.5" />
</ScrollViewer>
<TextBox x:Name="ZoomTextBox" Grid.Row="1" TextWrapping="Wrap" Text="Zoom: 100%" IsEnabled="False" Panel.ZIndex="10" BorderThickness="0" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontSize="20"/>
</Grid>
</UserControl>
I would have wanted there to be something like k:KinectRegion.ZoomFactor, but that isnt available. I've also tried to see what changes in the UI elements when I perform the zoom gesture, by writing the Height and ActualHeight properties of the ScrollViewer scrollViewer and Image navigationImage to a log file, but they show no change whatsoever.
When I perform the zoom gesture, I would like to get the value of zoom i.e. the current height and width of the image with respect to the original height and width.
This has nothing to do with Kinect SDK, this is more of a ScrollViewer zooming issue. There is no k:KinectRegion.ZoomFactor because zooming doesn't change the actual size of the image, it only performs some layout transformations, therefore you can get the zooming factor from LayoutTransform property of your Image.
Something like the following code should get the zooming factor:
UserControl.Code:
public NavigationImage()
{
InitializeComponent();
DataContext = this;
_zoom = 1.0;
}
double _zoom;
public string ZoomPercentage
{
get
{
return _zoom * 100 + "%";
}
}
private void scrollViewer_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta > 0)
{
_zoom += 0.1;
}
else
{
_zoom -= 0.1;
}
ScaleTransform scale = new ScaleTransform(_zoom, _zoom);
navigationImage.LayoutTransform = scale;
OnPropertyChanged("ZoomPercentage");
e.Handled = true;
}
UserControl.Xaml:
<UserControl x:Class="ImageNav.NavigationImage" ... >
<Grid Grid.RowSpan="2">
<ScrollViewer Name="scrollViewer" Grid.Row="0" PreviewMouseWheel="scrollViewer_MouseWheel"
....
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
k:KinectRegion.IsHorizontalRailEnabled="true" k:KinectRegion.IsVerticalRailEnabled="true"
k:KinectRegion.ZoomMode="Enabled"
>
<Image Name="navigationImage" RenderTransformOrigin="0.5, 0.5"/>
</ScrollViewer>
<TextBox x:Name="ZoomTextBox" Grid.Row="1" Text="{Binding ZoomPercentage, Mode=OneWay}" .... />
</Grid>
</UserControl>

Categories