Why the Path and Polyline have different renderings in WPF? - c#

Why the Path and Polyline have different renderings in WPF?
This is happening both in code and blend, maybe a I missing something or this
is just a anti aliasing effect.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="GeometryMonky.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
<Grid x:Name="LayoutRoot">
<Path Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF0000FF" Margin="100,10,0,0" Data="M289,39 L333,173" Width="1" HorizontalAlignment="Left" Height="100" StrokeThickness="1"/>
<Polyline Stroke="#FF0000FF" Margin="115,178,417,168" StrokeThickness="1" Width="100" Height="100">
<Polyline.Points>
<Point>10,0</Point>
<Point>10,100</Point>
</Polyline.Points>
</Polyline>
</Grid>
</Window>
Image sample from Blend:
http://img190.imageshack.us/img190/2965/wpfsmaple.png
Development system:
WinXP SP2, VS 2008 + SP1

It has to do with drawing modes of non-text objects. I tried setting the polyline object like the article linked below says and it does make it look just like the path.
So, short answer is it has to do with anti-aliasing. Here is the article: Single Pixel Lines
If you want the command here it is, give your polyline a Name and then add the following to the code behind.
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
// THIS IS THE LINE THATS IMPORTANT
pLine.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
}
}
Your xaml change here:
<Polyline x:Name="pLine" Stroke="#FF0000FF" Margin="115,178,417,168" StrokeThickness="1" Width="100" Height="100">
<Polyline.Points>
<Point>10,0</Point>
<Point>10,100</Point>
</Polyline.Points>
</Polyline>
This will make your polyline object look just like your Path object. However changing the Path to use unspecified does not do anything so you can make your other objects look similar to the path but not vice versa.

Put this in your Path or Polyline xaml tag
RenderOptions.EdgeMode="Aliased"

Related

UserControl renders with no width in designer

I have a UWP UserControl that contains a path element, the Data property of the path is bound to a string property of the UserControl called Icon. When I add my control to a page and set it's Icon property to a resource item, the control doesn't render the icon and has 0 width in the designer. When I deploy the application to my device the control renders as expected. Is there any way to fix this?
For reference, I'm trying to build a simple toolbar that has a bunch of clickable icons. I'm sure there are other ways of achieving this but I'm using this as a learning as my XAML skills are pretty lacking. My code can be found below.
MainPage.xaml
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Stretch">
<local:ActionIcon IconData="{StaticResource Test}" ></local:ActionIcon>
</StackPanel>
ActionIcon.xaml
<UserControl x:Name="userControl"
x:Class="UwpTest.ActionIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UwpTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="200"
d:DesignWidth="200">
<Viewbox Stretch="UniformToFill">
<Path Stretch="UniformToFill"
Data="{Binding IconData, ElementName=userControl}"
Fill="Black" />
</Viewbox>
</UserControl>
ActionIcon.xaml.cs
public sealed partial class ActionIcon : UserControl
{
public ActionIcon()
{
InitializeComponent();
}
public string IconData
{
get
{
return (string) GetValue(IconDataProperty);
}
set
{
SetValue(IconDataProperty, value);
}
}
public static readonly DependencyProperty IconDataProperty = DependencyProperty.Register(
"IconData", typeof(string), typeof(ActionIcon), new PropertyMetadata(default(string)));
}
ResourceDictionary Entry
<x:String x:Key="Test">M10,16.5V7.5L16,12M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z</x:String>
In a nutshell, the problem is that the types of IconData and Path.Data don't match. While IconData is a string, Path.Data wants a Geometry. So if you want to put the path's data in a resource dictionary, its type has to be Geometry or one of its subclasses. Consider, that WPF won't throw an exception when a binding fails. Instead you get a message in the Output-Window of Visual Studio.
But why can I use a string when I set the Path.Data-Property directly?
The Path never really gets a string. When the XAML parser gets a wrong type for a property, it looks at the class of the type it expected. It's searching there for a TypeConversion-Attribute. When the parser looks at Geometry, it finds such an attribute:
[TypeConverter(typeof(GeometryConverter))]
abstract partial class Geometry
The attribute specifies a TypeConverter. For Geometry it is GeomtryConverter, which can convert strings to Geometry. There's an article at msdn about that, if you want to know more: How to: Implement a Type Converter
Fine, but how do I use Geomtries in ResourceDictionaries?
The thing becomes clear once you try to create an path without asiging a string to Path.Data. A simple bezier curve before:
<Path Data="M 10,100 C 10,300 300,-200 300,100" />
and after:
<Path>
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="10,100">
<BezierSegment Point1="10,300" Point2="300,-200" Point3="300,100"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
The TypeConverter produces such an output. Only the points are again converted by a TypeConverter. However, the next step is simple: Just put the PathGeometry in the ResourceDictionary.
As a little side node: You can avoid using ElementName for every binding by setting the user controls DataContext to itself:
<UserControl DataContext={Binding RelativeSource={RelativeSource Self}}" />

Bing Maps in C# - Change Pushpin Image

I've been researching all over the internet for a way to change the pushpin image in the Bing Maps C# control. The closest that I came was using the following solution:
Change image for pushpin WPF
It is not entirely what I'm looking for, as I want to be able to change the color of the push pin as well as add a label.
The above solution is basically an image that is drawn over a push pin without additional functionality such as adding a label. I want to be able to easily change an image while having custom label functionality.
Is there any other way of doing this? An alternative would be to make use of "standard" Bing push pin graphics and be able to change the size. However it seems this functionality is not available in the C# control
This following blog post answers my questions:
http://dennis.bloggingabout.net/2012/10/17/bing-maps-on-wpf-and-custom-pushpin-tutorial-for-pixelsense/
Surprisingly this is the only question about this topic in SOF (the other one is closed). To complete newbies in WPF (like me) it is hard to find good and at the same time simple information, so I will show how I managed to use custom images in programatically added pushpins in VB.NET:
This is my MainWindow.xaml file:
<Window x:Class="MainWindow"
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"
xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"
xmlns:local="clr-namespace:MyBingMapsApp"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ControlTemplate x:Key="PushpinControlTemplate" TargetType="m:Pushpin">
<Grid>
<Rectangle Width="24" Height="24">
<Rectangle.Fill>
<ImageBrush ImageSource= "Resources/marker_green.png"/>
</Rectangle.Fill>
</Rectangle>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<m:Map x:Name="myMap"
CredentialsProvider= "xxxxxx mycredentialskey xxxxxxxx"
Center="42.13618,-0.40822"
ZoomLevel="15">
</m:Map>
</Grid>
</Window>
As you can see, you must define a ControlTemplate whose TargetType="m:Pushpin"
There you can draw whatever you need. The simplest: use an image from your resources.
Important: change image "Build action" to Resource (click on the image in your resources folder of the Solution Explorer and change it in Advanced settings). Otherwise you will have to hardwrite the image path or use Uris or more complicated stuff
Now you are ready to create a pushpin wherever you need and assign your template:
mypin = New Pushpin
mypin.Location = New Location(mylat, mylon)
mypin.ToolTip = "This is a pushpin with custom image"
Dim mytemplate As System.Windows.Controls.ControlTemplate = FindResource(“PushpinControlTemplate”) 'here of course you must put the key name of your template
mypin.Template = mytemplate

<Image /> displays image at design-time but not at runtime; why?

I'm trying to insert an image into my Windows Store app and it appears in design-time in the XAML editor but at runtime the image does not appear.
I'm pretty sure I'm using the right code here, and I have added the logo to the Assets folder however it still doesn't appear at runtime. If I got it wrong with the code or the Assets folder then it wouldn't even be appearing at design-time in the editor I think so what gives?
XAML:
<Page
x:Class="AppName.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppName"
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}">
<Image Source="Assets\Logos\16380.png"
Stretch="None"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="120, 0, 0, 0"
/>
</Grid>
</Page>
I've managed to solve this problem.
When inserting images onto a page in XAML, you need to right-click the image file in Solution Explorer, click Properties and then make sure its Build Action is set to Content and then set Copy to Output Directory to Copy if newer. You also need to use forward slashes (/) and not back-slashes ().

What is the equivalent way to use Bitmap,Graphics,PictureBox & BitmapCopy() in WPF?

I'll try to explain my problem clearly.
I have a working code in WinForms that has a Board (PictureBox) that shows an image thats generated from a list of users controls (win-forms) by the function UserControl.BitmapCopy() for each user control.
This process begins with a blank image (Graphic type), and for each user control I draw it in a specific location with the function BitmapCopy() of the user control.
The result is an image that looks like a real form (with buttons,labels,etc.), but it’s just an image.
Then I show this image in a picture Box.
Now I need to implement this code in WPF, but I can’t generate an image of each user control with BitmapCopy().
I found this code that does it, so now I can generate a bitmap for each user control, but I don’t know what is the best way to create the Big Board that eventually shows a bitmap that has all the user controls images inside it, in different locations.
I would appreciate any help.
This is the equivalent in WPF:
<Window x:Class="MiscSamples.VisualBrush"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VisualBrush" Height="300" Width="300" x:Name="Window">
<StackPanel>
<TextBlock Text="Hi, Im a Window!"/>
<TextBox Text="This is a TextBox"/>
<Slider Width="200"/>
</StackPanel>
<Window.ToolTip>
<ToolTip DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
<Grid Height="400" Width="400">
<Grid.Background>
<VisualBrush Visual="{Binding}"/>
</Grid.Background>
</Grid>
</ToolTip>
</Window.ToolTip>
</Window>
The Window's ToolTip consists of a grid painted with VisualBrush whose Visual is the Window itself. It looks like this:
As you can see, Exactly 0 lines of C# code are required to achieve the same in WPF.

OuterGlow effect in WPF not working with layered window?

can any one tell me why /no/ outerglow effects are working on my WPF Window? here is an example of the code:
<Window x:Class="SocialShock_WPF_Client.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
AllowsTransparency="True"
WindowStyle='None'
Background="Transparent"
Loaded="Window_Loaded">
<Grid>
<Rectangle Margin="12" Name="rectangle1" Fill="#FFB75050">
<Rectangle.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="Black" GlowSize="20" />
</Rectangle.BitmapEffect>
</Rectangle>
</Grid>
</Window>
and the resulting image:
http://img408.imageshack.us/img408/6213/1c1761f31ce6408d948e266.png
No glow around the edge.
not only is the glow not appearing on the rectangle, but any other controls i add to the window cannot accept glows either.
EDIT: its in .Net 4.0
BitmapEffects are no longer supported in .NET 4.0.
From MSDN
Important In the .NET Framework 4 or
later, the BitmapEffect class is
obsolete. If you try to use the
BitmapEffect class, you will get an
obsolete exception. The non-obsolete
alternative to the BitmapEffect class
is the Effect class. In most
situations, the Effect class is
significantly faster.
There isn't a really good substitute but you can try to use a DropShadowEffect with a ShadowDepth of 0. Example
<Rectangle Margin="12" Name="rectangle1" Fill="#FFB75050">
<Rectangle.Effect>
<DropShadowEffect ShadowDepth="0"
Color="Black"
Opacity="1"
BlurRadius="12"/>
</Rectangle.Effect>
</Rectangle>
If I understood you comment correctly,
Adding the effect in code behind
DropShadowEffect dropShadowEffect = new DropShadowEffect();
dropShadowEffect.ShadowDepth = 0;
dropShadowEffect.Color = Colors.Black;
dropShadowEffect.Opacity = 1;
dropShadowEffect.BlurRadius = 12;
rectangle1.Effect = dropShadowEffect;
Modifying the effect in code behind
DropShadowEffect dropShadowEffect = rectangle1.Effect as DropShadowEffect;
dropShadowEffect.BlurRadius = 24;

Categories

Resources