Search code examples
c#wpfimagetextblockstackpanel

How to add small header (textblock) near the top left corner of the Image?


I've got an app, which shows preview of documentation, using thumbnails. What I need, is to have a small header (text) near each thumbnail of Image. The header should be to the left from the image, on the top, how is shown on the picture. I managed to add textblock with number of page on the image. Please, give your advices. The image thumbnails are generated dynamically in the code behind. Here is part of code behind. I managed to achieve my purpose, but I want to find more elegant solution.

Image

RowDefinitionCollection rd = gridPreview.RowDefinitions;
ColumnDefinitionCollection cd =gridPreview.ColumnDefinitions;

int columnAmount = Convert.ToInt32(Math.Truncate(gridPreviewWidth / GetThumbnailSizes(tiffImageList).Item2));
gridPreviewHeight = ((tiffImageList.Count / columnAmount) + 1) * GetThumbnailSizes(tiffImageList).Item1 + 100;

for (int i = 0; i < (tiffImageList.Count / columnAmount) + 1; i++)
{
    rd.Add(new RowDefinition() { Height = GridLength.Auto });
    for (int j = 0; j < columnAmount; j++)
    {
        cd.Add(new ColumnDefinition() { Width = GridLength.Auto });
    }
}

foreach (var tiffImage in tiffImageList)
{
    if (columnIndex == columnAmount)
    {
        columnIndex = 0;
        rowIndex++;
    }


    Image imagePreviewItem = new Image();
    imagePreviewItem.Margin = new Thickness(20, 20, 20, 20);
    TextBlock textBlock = new TextBlock();
    textBlock.Margin = new Thickness(-370,0,0,0);
    textBlock.Text = $"{tiffImage.index.ToString()}"; // Header text

    RenderOptions.SetBitmapScalingMode(imagePreviewItem, BitmapScalingMode.HighQuality);
    imagePreviewItem.Name = $"Image{tiffImage.index.ToString()}";


    imagePreviewItem.Source = tiffImage.image.Thumbnail;

    StackPanel stackPanel = new StackPanel();
    stackPanel.Width = imagePreviewItem.Width + 50;
    stackPanel.Height = imagePreviewItem.Height + 50;
    stackPanel.Children.Add(textBlock);
    stackPanel.Children.Add(imagePreviewItem);

    Border border = new Border();
    border.BorderBrush = Brushes.LightGray;
    border.BorderThickness = new Thickness(1);
    Thickness margin = border.Margin;
    border.Margin = new Thickness(20, 20, 20, 20); ;
    border.Child = stackPanel;
    Grid.SetColumn(border, columnIndex);
    Grid.SetRow(border, rowIndex);

    gridPreview.Children.Add(border);
}

Solution

  • instead of adding textBlock with number into stackPanel, add it into gridPreview on top of border in the top left corner:

    foreach (var tiffImage in tiffImageList)
    {
        if (columnIndex == columnAmount)
        {
            columnIndex = 0;
            rowIndex++;
        }
    
        Image imagePreviewItem = new Image();
        imagePreviewItem.Margin = new Thickness(20, 20, 20, 20);
        TextBlock textBlock = new TextBlock();
        textBlock.VerticalAlignment = VerticalAlignment.Top;
        textBlock.HorizontalAlignment = HorizontalAlignment.Left;
        textBlock.Margin = new Thickness(40, 40, 40, 40);
        textBlock.Text = $"{tiffImage.index.ToString()}"; // Header text
    
        RenderOptions.SetBitmapScalingMode(imagePreviewItem, BitmapScalingMode.HighQuality);
        imagePreviewItem.Name = $"Image{tiffImage.index.ToString()}";
        imagePreviewItem.Source = tiffImage.image.Thumbnail;
    
        StackPanel stackPanel = new StackPanel();
        stackPanel.Width = imagePreviewItem.Width + 50;
        stackPanel.Height = imagePreviewItem.Height + 50;
        stackPanel.Children.Add(imagePreviewItem);
    
        Border border = new Border();
        border.BorderBrush = Brushes.LightGray;
        border.BorderThickness = new Thickness(1);
        Thickness margin = border.Margin;
        border.Margin = new Thickness(20, 20, 20, 20);
        border.Child = stackPanel;
        Grid.SetColumn(border, columnIndex);
        Grid.SetRow(border, rowIndex);
    
        Grid.SetColumn(textBlock, columnIndex);
        Grid.SetRow(textBlock, rowIndex);
    
        gridPreview.Children.Add(border);
        gridPreview.Children.Add(textBlock);
    }