Question

I have a Border (contains a Canvas inside) defined as follows where I want to dynamic show the position of mouse when moving over the Canvas:

In .xmal:

<Border x:Name="cwgLayoutDesignBorder" BorderThickness="0"
        Width="600" Height="800" BorderBrush="Yellow">
    <ItemsControl x:Name="linecontrol">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas  Background="Green" MouseMove="Canvas_MouseMove"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Canvas>
                    ... 
                </Canvas>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Border>

In .cs:

private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
    Point p = e.GetPosition(linecontrol);

    this.Title = "(" + Convert.ToInt32(p.X) + ", " + Convert.ToInt32(p.Y) + ")";
}

I found that the position returned by the mouse turned out to be: x in [0, 600] and y in [1, 800]. However, given my definition, I thought the result should be [0, 599] and y in [0, 799] instead. Why are they inconsistent? Or how should I get the correct position of the mouse?

Was it helpful?

Solution

It's x[0,599] and y[0,799]. If you try and draw a pixel at 0,0 it will be the top left pixel and if you draw at 600,800 it will draw outside the Canvas. Draw a simple 50x50 canvas and run this against it to see:

for (int x = 0; x < 51; x++)
{
    for (int y = 0; y < 51; y++)
    {
        var rect = new Rectangle
        {
            Stroke = Brushes.White,
            StrokeThickness = 1,
            Width=1,
            Height=1
        };

        if (x == 0 & y == 0)
        {
            rect.Stroke = Brushes.LimeGreen;
        }

        if (x == 50 & y == 50)
        {
            rect.Stroke = Brushes.LimeGreen;
        }

        Canvas.SetLeft(rect, x);
        Canvas.SetTop(rect, y);
        youCanvasNameHere.Children.Add(rect);
    }
}

You might need to use magnify.exe to see it though.

OTHER TIPS

You are getting the correct mouse position and using the correct method to do so. If your Border element has a Width of 600 and its Height is set to 800, then any contained UI element will inherit those same values. That means that your linecontrol ItemsControl element will also be 600x800. Only if your Border.BorderThickness or Border.Padding (or other size changing property) is set to a positive value will the size of the contained control change.

Even then, if your Border.BorderThickness property was set to 1, then your ItemsControl.Width would be 598 and not 599, so I suspect that you may have misread your values. I used your code to run your experiment and found that Width and Height values went from 0 to 600 and 0 to 800 respectively. So, either you've read your values incorrectly, or you need to edit your question to provide all relevant code required to successfully reproduce your problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top