I'm creating a button style that contains a straight line:
<Button VerticalAlignment="Center" HorizontalAlignment="Center">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#F0F0F0"/>
<Setter Property="Width" Value="50"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<Path Stroke="Black" StrokeThickness="1" Data="M0,0 L10,0"
VerticalAlignment="Center" HorizontalAlignment="Center"
SnapsToDevicePixels="True" UseLayoutRounding="True"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
But instead of a 1px wide line, I always get a 2px wide line:
I tried using the following (both in relation to the parent Grid
and the Path
element itself): UseLayoutRounding="True"
, SnapsToDevicePixels="True"
, RenderOptions.BitmapScalingMode="Fant"
, RenderOptions.EdgeMode="Aliased"
. None of this helped me and doesn't make the line look normal. Previously, one of the above or a combination of them always helped.
I tried to determine the system DPI value for the window and the value that WPF knows:
PresentationSource presentationSource = PresentationSource.FromVisual(window);
double wpfDpi = 96.0 * presentationSource.CompositionTarget.TransformToDevice.M11;
double currentDpi = GetDpiForWindow(hWnd);
Both values are the same (120) - the application knows about the scale.
Taget platform: NET Framework 4.5
OS: Windows 10 21H2
Add RenderOptions.EdgeMode="Aliased"
to your Path
object.
This will force a 1 pixel wide line onto exact pixel boundaries, giving you a crisp graphic.
You don't need UseLayoutRounding
or SnapsToDevicePixels
.
<Path Stroke="Black"
StrokeThickness="1"
Data="M0,0 L10,0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
RenderOptions.EdgeMode="Aliased" />