Question

I overriden Border control and in my overriden OnRender I do:

protected override void OnRender(System.Windows.Media.DrawingContext dc)
        {
            this.SnapsToDevicePixels = true;
            this.VisualEdgeMode = EdgeMode.Aliased;
            var myPen = new Pen(new SolidColorBrush(Colors.LightGray), 1);
            dc.DrawLine(myPen, new Point(1, 1), new Point(1, RenderSize.Height - 1));
            return;

Which give me this result: enter image description here

Question:

Is anybody can tell me why my code draw a line that start at (0,1) while it is suppose to start at (1, 1) like written in code ?

My DPI are 96, 96.

For ref, this is my xaml:

<Window xmlns:MyControls="clr-namespace:MyControls;assembly=MyControls"  x:Class="TestControls.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">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>


        <MyControls:Border3D BorderThickness="3" BorderBrush="Aqua">
            <Rectangle Width="74" Height="3" HorizontalAlignment="Left">
                <Rectangle.Fill>
                    <SolidColorBrush Color="#40FF0000">

                    </SolidColorBrush>
                </Rectangle.Fill>
            </Rectangle>
        </MyControls:Border3D>

        <Rectangle  Grid.Row="1" Grid.Column="0" Width="80" Grid.ColumnSpan="2" HorizontalAlignment="Left">
            <Rectangle.Fill>
                <SolidColorBrush Color="LightGray"></SolidColorBrush>
            </Rectangle.Fill>
        </Rectangle>

    </Grid>
</Window>
Was it helpful?

Solution

Keep in mind that (0, 0) is not the center of the upper left pixel. Instead it is the upper left corner of that pixel. In order to draw a line with a stroke thickness of 1 in the middle of the second pixel column (with index 1) you would have to draw from (1.5, 1) to (1.5, RenderSize.Height - 1):

dc.DrawLine(myPen, new Point(1.5, 1), new Point(1.5, RenderSize.Height - 1));

Setting SnapsToDevicePixels = true made your line snap to the left by half a pixel.


If you would use PenLineCap.Square for both the StartLineCap and EndLineCap properties of the line's Pen, you could draw from exactly one pixel center to the other:

var myPen = new Pen(Brushes.LightGray, 1);
myPen.StartLineCap = PenLineCap.Square;
myPen.EndLineCap = PenLineCap.Square;
dc.DrawLine(myPen, new Point(1.5, 1.5), new Point(1.5, RenderSize.Height - 1.5));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top