Search code examples
wpfbackgroundwindow

WPF Window Background ImageBrush not tiling


I have a window with a background image. The image may change at runtime which really should not matter for this.

I want the image to be fixed to the top left (which it is) and not scale (which is also correct. But I need the image to repeat (tile) when the window is made larger than the image. I am doing ...

What am i missing?

TIA


Solution

  • You need to set the TileMode property as well as the Viewport and ViewportUnits:

    For example:

    <Window.Background>
        <ImageBrush ImageSource="myImage.png"
            Viewport="0,0,300,300"
            ViewportUnits="Absolute"
            TileMode="Tile"
            Stretch="None"
            AlignmentX="Left"
            AlignmentY="Top"  />
    </Window.Background>
    

    Note: the second 2 segments of the Viewport attribute indicate the desired size of each repetition. If you want to display the entire image, these should be the width and height of the image.

    Example output: tiled magnifiers

    Edit in response to comments

    If you don't know the size of the image to specify in the Viewport property, you can use a Binding with an IValueConverter to calculate it from the image. I am convinced there must be a better way of doing this, but I haven't found one yet!

    XAML:

    <Window.Resources>
        <local:Converter x:Key="Converter" />
    </Window.Resources>
    <Window.Background>
    
        <ImageBrush ImageSource="myImage.png"
        ViewportUnits="Absolute"
        TileMode="Tile"
        Stretch="None"
        AlignmentX="Left"
        AlignmentY="Top" 
        Viewport="{Binding ImageSource, RelativeSource={RelativeSource Self}, Converter={StaticResource Converter}}"/>
    </Window.Background>
    

    Value converter:

    public class Converter : IValueConverter
    {
        #region IValueConverter Members
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var source = (ImageSource)value;
            return new Rect(0,0,source.Width, source.Height);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    
        #endregion
    }