0

I have implemented re-ordering (drag and drop) of ListView items using code in this article, with minor changes. Also View property of the ListView is set to "Tile" and Alignment set to "Left". Code works fine, however Insertion Mark is not entirely in the middle between the Items.

enter image description here

Would it be possible to adjust location of the mark? It is offset by 1px. I also tried to change TileSize but spacing and offset remains the same.

Update: I tried to offset Item drawing by changing corresponding rectangles, however have problem with selected Item rectangle (bottom part is not drawn properly). Also tried to offset Items by simply adding e.Graphics.TranslateTransform(0, 1); to listView1_DrawItem event handler but got same unexpected result.

enter image description here

Sample code where the rectangles are drawn. Credits to Uwe Keim.

private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    e.DrawDefault = false;
    e.Graphics.TranslateTransform(0, 1);

    Brush backgroundBrush;
    Brush textBrush;

    if (e.Item.Selected)
    {
        backgroundBrush = SystemBrushes.Highlight;
        textBrush = SystemBrushes.HighlightText;
    }
    else
    {
        backgroundBrush = SystemBrushes.Window;
        textBrush = SystemBrushes.WindowText;
    }
    e.Graphics.FillRectangle(backgroundBrush, e.Bounds);    // Draw Background Rectangle

    const int squareDistance = 1;
    int squareWidth = (e.Bounds.Height - 2) * 2 * squareDistance;
    int squareHeight = e.Bounds.Height - 2 * squareDistance;

    int offsetX = e.Bounds.Left + squareDistance;
    int offsetY = e.Bounds.Top + squareDistance;

    Rectangle r = new Rectangle(offsetX, offsetY, squareWidth, squareHeight);

    using (Brush brush = new SolidBrush(Color.Red))
    {
        e.Graphics.FillRectangle(brush, r);                 // Draw Item Rectangle
    }

    Rectangle r2 = new Rectangle(r.Left, r.Top, r.Width - 1, r.Height - 1);
    Pen pen = SystemPens.ControlDarkDark;
    e.Graphics.DrawRectangle(pen, r2);                      // Draw Boarder of Item Rectangle

    offsetX += squareWidth + squareDistance * 2;

    RectangleF rf = new RectangleF(offsetX, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height);
    e.Graphics.DrawString(e.Item.Text, e.Item.Font, textBrush, rf); // Draw Text
}
Creek Drop
  • 464
  • 3
  • 13
  • I've not used this but maybe adjust top margin of the `DataTemplate` to provide a bit more space? – Jeff Jan 04 '21 at 02:07
  • You should show the code that drawing the items. Note that in Tile view, there's a small *defect* when the Insertion Mark is drawn (something you cannot control) and you have one or more Sub Items: the clip rectangle is moved 2 pixels to the left. This problem is not generated in the other views. Anyway, the problem can be fixed if you post the code used to draw those rectangles. See the example here, as reference: [How to change default selection color of a ListView?](https://stackoverflow.com/a/55525989/7444103) – Jimi Jan 04 '21 at 09:17
  • Thanks for response. Issue is reproducible also with code in answer @Jimi posted. I have added `e.Graphics.TranslateTransform(0, 1);` to `listView1_DrawItem`. When I use selection rectangle or trying to select items, control leaves bottom part of selected background not cleared i.e. Items background is not drawn properly. – Creek Drop Jan 04 '21 at 13:21
  • Don't use `Graphics.TranslateTransform()`. There's no need for it here. Use another View mode. Possibly, as mentioned, post the code you're using: it could be useful to others. – Jimi Jan 04 '21 at 14:05
  • With another View modes (e.g. LargeIcon) the marker is still not in the right place. I need to offset either graphics or marker. – Creek Drop Jan 04 '21 at 14:57
  • The problem here is the way you calculate the drawing bounds and the use of `Graphics.DrawString()`. As shown in the sample code, the ListView uses `TextRenderer.DrawText()` and different alignments based on the View Mode. In Tile View, the alignment is `TextFormatFlags.Bottom`, for example. Otherwise is `TextFormatFlags.VerticalCenter`. Some modes have left and right padding added, others don't. You cannot treat all View Modes the same way. As mentioned, Tile View has a *defect*, but it slides the clip rectangle to the left, not towards the bottom. – Jimi Jan 04 '21 at 20:57

0 Answers0