themadmax
themadmax

Reputation: 2404

Create After/Before Image slider control in WPF

I want to create a Before/After control like this https://codepen.io/dudleystorey/pen/HkwBo in WPF.

How to Stretch image at startup, and not stretch on splitter move, and made the same origin for two images.

<UserControl x:Class="BeforeAfterImage.BeforeAfterImageCtrl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="5" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Image Stretch="None" Name="Before" Grid.Column="0" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" />
    <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center" />
    <Image Stretch="None" Name="After" Grid.Column="2" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" />
</Grid>

Upvotes: 3

Views: 1706

Answers (3)

Steven Rands
Steven Rands

Reputation: 5421

You could use a single-cell Grid to stack the two images on top of one another, then use a Slider control to adjust the width of the image that is "on top". (I used the same images as in your linked example, which are incidentally slightly different sizes; a bit odd given what the UI is trying to illustrate, but hey-ho).

<Window x:Class="WpfApplication2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <Image x:Name="BeforeImage" HorizontalAlignment="Left"
            Source="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/photoshop-face-before.jpg" />
        <Rectangle HorizontalAlignment="Left" Width="{Binding Value, ElementName=Slider}">
            <Rectangle.Fill>
                <ImageBrush ImageSource="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/photoshop-face-after.jpg"
                    Stretch="UniformToFill" AlignmentX="Left" AlignmentY="Top" />
            </Rectangle.Fill>
        </Rectangle>
        <Slider x:Name="Slider" Maximum="{Binding ActualWidth, ElementName=BeforeImage}"
            VerticalAlignment="Bottom" Margin="0,0,0,40" />
    </Grid>
</Window>

Which looks like this when running:

Illustrative example

The only thing you'll probably want to do is style the Slider control to change its appearance to something more fitting. You should be able to find plenty of WPF control styling examples online.

Note that if the two images have different or non-standard DPIs then this technique probably won't work properly.

Upvotes: 4

Clemens
Clemens

Reputation: 128060

You may have the lower Image span all Grid columns, and bind the upper Image's Width and Height to the size of the lower one. However, everything is now left-aligned which might not be an issue of the UserControl is put into an appropriate container element.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Image x:Name="After" HorizontalAlignment="Left"
           Grid.ColumnSpan="3"
           Source="C:\Users\Public\Pictures\Sample Pictures\Koala.jpg"/>
    <Image x:Name="Before" HorizontalAlignment="Left"
           Width="{Binding ActualWidth, ElementName=After}"
           Height="{Binding ActualHeight, ElementName=After}"
           Source="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg"/>
    <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center"/>
</Grid>

Upvotes: 1

jgCallahan
jgCallahan

Reputation: 43

I have done this before using a Canvas.

I had both images occupy the same space on the Canvas with the image on the left having a larger Z-Index than the image on the right so that it sits on top. Then put a slider in starting all the way left.

The only thing you need to do then is as the slider moves to the right, set the left images with to be the horizontal position of the slider.

Hope this helps

Upvotes: 0

Related Questions