WPF transparent text with opaque background - c#

I need transparent text with opaque background with WPF/XAML. Is that possible?
Here is an example, but I don't use css: css, transparent text with opaque background
Maybe there is a manner in order to produce transparent text with opaque background with c#?
The background should be an Image, I tried it with a Canvas:
<Grid>
<!-- shows only a black box, but should show red text on black background-->
<Canvas Width="100" Height="20" Background="Red"/>
<TextBlock Text="My text" Foreground="#00000000" Background="#FF000000"/>
</Grid>

You can set it using the Opacity property on the SolidColorBrush. It takes values from 0 to 1. Where 0 is complete transparency and 1 complete opacity. But if you set the text transparent then what you will see is the background of the text box. In the example I've set partial opacity so you can see the text is greyish.
<TextBlock Text="Test" Background="Red" Width="100" Height="100">
<TextBlock.Foreground>
<SolidColorBrush Opacity="0.25" Color="Black"/>
</TextBlock.Foreground>
</TextBlock>
Other thing to get the transparency and see the background of the control beneath the text block is to set transparent foreground and partially transparent background.

U can make this by converting your text to Path and then Make Clipping On your white Rectangle with that Path.
Try this:
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox x:Name="textToMask" TextChanged="textToMask_TextChanged" />
<Rectangle Grid.Row="1" x:Name="target" Fill="Yellow"/>
</Grid>
c# code
private void textToMask_TextChanged(object sender, TextChangedEventArgs e)
{
Typeface face = new Typeface("Candara");
FormattedText tx = new FormattedText(textToMask.Text, Thread.CurrentThread.CurrentUICulture, FlowDirection.LeftToRight, face, 70, Brushes.Black);
Geometry textGeom = tx.BuildGeometry(new Point(0, 0));
Rect boundingRect = new Rect(new Point(-100000, -100000), new Point(100000, 100000));
RectangleGeometry boundingGeom = new RectangleGeometry(boundingRect);
GeometryGroup group = new GeometryGroup();
group.Children.Add(boundingGeom);
group.Children.Add(textGeom);
target.Clip = group;
}

Related

Does ThemeShadow Class (UWP on Windows 1903) support only rectangle shapes?

I try the following code which is almost the same than example code on Microsoft web site. Only change is that I changed first Rectangle to Ellipse.
<Grid>
<Grid.Resources>
<ThemeShadow x:Name="SharedShadow" />
</Grid.Resources>
<Grid x:Name="BackgroundGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
<Ellipse x:Name="Ellipse1" Height="100" Width="100" Fill="Turquoise" Shadow="{StaticResource SharedShadow}" />
<Rectangle x:Name="Rectangle1" Height="100" Width="100" Fill="Turquoise" Shadow="{StaticResource SharedShadow}" />
</Grid>
Here is the simple C# code behind:
SharedShadow.Receivers.Add(BackgroundGrid);
Ellipse1.Translation += new Vector3(0, 0, 16);
Rectangle1.Translation += new Vector3(120, 0, 32);
Shadows appears on the screen but shadow connected to Ellipse element is still shape of rectangle. So , is it so that this new class support only Rectangle shapes like Dialog, Grid, StackPanel (without any CornerRadius) etc. but not any other shapes like Ellipse, Text etc.

Transparent background for text by opacity

I'm a little new in wpf. I want to make transparent background for the text. I achieved it with the AllowsTransparency = true; background = Colors.Transparent but the animation was like chopping. I read here Strange Choppy WPF Animation
that's common for the AllowsTransparency property, so I want to make it by opacity. I have XAML code:
<Grid x:Name="Gridd">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Viewbox x:Name="MainWindow1">
<TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="00:00:00" FontFamily="Digital-7 Mono" FontSize="50" Grid.Row="0" Grid.Column="0"/>
</Viewbox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"
VerticalAlignment="Bottom" />
</Grid>
I want to change opacity dynamically, each time I try to make background transparent by opacity, the text vanish also. Any tips?
I solved it with OpacityMask which "choose" color to make transparent when Opacity on the window is set to 0. Now i can choose the same Color for the OpacityMask and Background. The background vanish and text is still visible

How to use transform for different children of a grid cell to change size synchronously?

There are two elements in one grid cell, and when I use layout transform for the grid only the ink canvas is transformed and the image not changed at all . And when I use scaled transform instead of layout they both change but the problem is that it will overflow the scroll viewer.
C# :
private void editor_mouseWheel(Object sender , MouseWheelEventArgs e)
{
Matrix m = grid.LayoutTransform.Value;
if (e.Delta > 0)
grid.ScaleAtPrepend(1.1,1.1,0,0);
else
grid.ScaleAtPrepend(1/1.1,1/1.1,0,0);
grid.LayoutTransform = new MatrixTransform(m) ;
grid.UpdateLayout();
}
And XAML :
<ScrollViewer>
<Grid Name="grid" />
<Image Name="img" RenderTransformOrigin="0,0" />
<InkCanvas Name="editor" Background="Transparent" />
</Grid>
</ScrollViewer>
The LayoutTransform does actually affect the Image control. However, by default the Image control stretches its image to fit its bounds.
You may set the Stretch property to None:
<Grid Name="grid">
<Image Name="img" Stretch="None" />
<InkCanvas Name="editor" Background="Transparent" />
</Grid>

Modify Bing Maps Anchor Point

I am working on a C#/XAML Universal Windows store app and I need to plot a custom control on a Bing map control. The problem is I cannot find any method to modify the anchor point which is by default Point(0,0) which anchor the control to upper left corner. I need something equivalent to MapControl.SetNormalizedAnchorPoint in Windows Phone. I believe it is possible since the Bing Maps app controls has an anchor point at the bottom left corner. How is it done?
Edit:
Here's what my custom control looks like. What I want is for it to anchor to the location at the bottom left corner (blue circle) instead of the default top left (red circle).
Here what it looks like on the map control where it achors to the red circle instead of blue.
And here's my code behind
public void AddPushpin(BasicGeoposition location, string title, string subtitle = "")
{
var pin = new PinControl(title, subtitle);
pin.ApplyTemplate();
pin.UpdateLayout();
MapLayer.SetPosition(pin, location.ToLocation());
_pinLayer.Children.Add(pin);
}
Here's the lengthy XAML
<UserControl x:Class="ToulouseUniversal.CustomControls.PinControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ToulouseUniversal.CustomControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="100"
d:DesignWidth="200">
<Grid>
<Grid x:Name="LayoutRoot"
VerticalAlignment="Bottom">
<Polygon x:Name="labelPointer"
Points="0,0 0,0.5 15,15.5 15,0"
Margin="-15,0,0,0"
Grid.ColumnSpan="2"
Fill="{StaticResource TisseoBrush1}"
HorizontalAlignment="Left"
VerticalAlignment="Bottom" />
<Polygon Points="0,0 0,0.5 15,15.5 15,0"
Margin="-15,0,0,0"
Grid.ColumnSpan="2"
Fill="Black"
Opacity="0.3"
HorizontalAlignment="Left"
VerticalAlignment="Bottom" />
<Grid Margin="-15,0,0,15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Rectangle Height="4"
VerticalAlignment="Bottom"
Margin="14.5,-1,0.5,-3.5"
Grid.ColumnSpan="2">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Black"
Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="labelGrid"
Fill="{StaticResource TisseoBrush1}"
RadiusX="0"
RadiusY="0"
Grid.ColumnSpan="2"/>
<Rectangle Fill="White"
Opacity="0.2"
Width="3"
HorizontalAlignment="Left" />
<Rectangle Fill="White"
Grid.ColumnSpan="2"
Opacity="0.2"
Width="3"
HorizontalAlignment="Right" />
<Grid>
<BitmapIcon UriSource="ms-appx:///Assets/Icons/appbar.transit.bus.png"
Width="40" />
</Grid>
<StackPanel Grid.Column="1">
<TextBlock x:Name="labelTitle"
Text="A stop"
Margin="6,3,9,0"
Foreground="White"
TextWrapping="Wrap"
MaxWidth="180"
FontSize="20"
FontWeight="SemiBold" />
<TextBlock x:Name="labelSubtitle"
Text="connecting"
Margin="6,0,9,6"
Foreground="White"
TextWrapping="Wrap"
FontSize="12"
MaxWidth="180"
FontWeight="Light" />
</StackPanel>
</Grid>
</Grid>
</Grid>
Depending on what you're trying to achieve, it might be interesting to share more of your XAML code or at least the part of the code were you're creating the pushpin object as well as the associated option.
Anyway, in order to control the anchor, it might be interesting to be able to use custom control as a pushpin so basically, if you're using a Grid as the root control representing the pushpin, you can work to display multiple things and also work with the margin on children controls to move them in the Grid.
If you look at the article here, you will see how it can be done:
http://blogs.msdn.com/b/bingdevcenter/archive/2014/06/24/using-maps-in-universal-apps.aspx
See the interesting part of the code is:
public void AddPushpin(BasicGeoposition location, string text)
{
#if WINDOWS_APP
var pin = new Pushpin()
{
Text = text
};
MapLayer.SetPosition(pin, location.ToLocation());
_pinLayer.Children.Add(pin);
#elif WINDOWS_PHONE_APP
var pin = new Grid()
{
Width = 24,
Height = 24,
Margin = new Windows.UI.Xaml.Thickness(-12)
};
pin.Children.Add(new Ellipse()
{
Fill = new SolidColorBrush(Colors.DodgerBlue),
Stroke = new SolidColorBrush(Colors.White),
StrokeThickness = 3,
Width = 24,
Height = 24
});
pin.Children.Add(new TextBlock()
{
Text = text,
FontSize = 12,
Foreground = new SolidColorBrush(Colors.White),
HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center
});
MapControl.SetLocation(pin, new Geopoint(location));
_map.Children.Add(pin);
#endif
}
Here is a nice blog post solving your problem to simulate the anchor-point in custom control for Bing Maps.
The most interesting part:
In the XAML Bing Maps controls the easiest way to offset a pushpin or custom
UIElement that is being overlaid on the map like a pushpin is to specify
a negative margin value on the pushpin or UIElement
In your case it would be sufficient to apply the negative margin on the LayoutRoot Grid.

Image Border control wrap question

in the following example, my border wraps around the image. The border does not wrap tightly around the image because I use DecodePixelWidth to keep the aspect ratio. Two sides end up with the border right up against the image, and the other two have gaps from the control. Is there a clean way to have the border wrap the image while keeping the aspect ratio instead of setting the Image stretch to fill.
BitmapImage bitmapIkon = new BitmapImage();
bitmapIkon.BeginInit();
bitmapIkon.CacheOption = BitmapCacheOption.OnLoad;
bitmapIkon.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bitmapIkon.UriSource = new Uri(imagePath);
bitmapIkon.DecodePixelWidth = decodePixelWidth;
bitmapIkon.EndInit();
iImage.MinWidth=width;
iImage.MinHeight=height;
iImage.Source = bitmapIkon;
<Border Width="Auto" Height="Auto" Name="borderImageData" HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="Black" BorderThickness="1" CornerRadius="0">
<Image Name="iImage" Stretch="Uniform" />
</Border>
Something like this should work:
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Name="iImage" Text="Uniform" Margin="1" />
<Border Name="borderImageData" BorderBrush="Black" BorderThickness="1" CornerRadius="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
So effectively, the Grid sizes to fit the Image plus a margin of 1. The Border then stretches to fill the Grid, and draws it's border on top of the image.
If you are going to be using this a lot, then you may want to wrap it in a custom control.

Categories

Resources