Anleitung: So erstellen Sie eine Spiegelung

In diesem Artikel wird gezeigt, wie Sie VisualBrush verwenden, um eine Spiegelung zu erstellen. Da ein VisualBrush ein vorhandenes visuelles Element anzeigen kann, können Sie diese Fähigkeit nutzen, um interessante visuelle Effekte wie Spiegelungen und Vergrößerungen zu erzeugen.

Ein XAML-Element mit lateinischem Text und zwei Kreisen, deren Aufwärtsspiegelung darunter angezeigt wird.

XAML-Beispiel

Das folgende Beispiel verwendet VisualBrush, um eine Spiegelung von Border zu erstellen, die mehrere Elemente enthält.

<StackPanel Margin="25" Height="400">

    <!-- The object to reflect. -->
    <Border Name="ReflectedVisual" Width="400">
        <Border.Background>
            <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                <GradientStop Offset="0.0" Color="#CCCCFF" />
                <GradientStop Offset="1.0" Color="White" />
            </LinearGradientBrush>
        </Border.Background>
        <StackPanel Orientation="Horizontal" Margin="10">
            <TextBlock TextWrapping="Wrap" Width="200" Margin="10">
              Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
              Suspendisse vel ante. Donec luctus tortor sit amet est.
              Nullam pulvinar odio et wisi.
              Pellentesque quis magna. Sed pellentesque.
            </TextBlock>
            <StackPanel>
                <Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
                <Ellipse Margin="10" Height="50" Width="50" Fill="Purple" />
            </StackPanel>
        </StackPanel>
    </Border>

    <Rectangle Height="1" Fill="Gray" HorizontalAlignment="Stretch" />

    <!-- The object to contain the reflection.-->
    <Rectangle DataContext="{Binding ElementName=ReflectedVisual}"
               Height="{Binding Path=ActualHeight}" 
               Width="{Binding Path=ActualWidth}">
        <Rectangle.Fill>

            <!-- Creates the reflection. -->
            <VisualBrush Opacity="0.75" Stretch="None"
                         Visual="{Binding}">
                <VisualBrush.RelativeTransform>

                    <!-- Flip the reflection. -->
                    <TransformGroup>
                        <ScaleTransform ScaleX="1" ScaleY="-1" />
                        <TranslateTransform  Y="1" />
                    </TransformGroup>
                </VisualBrush.RelativeTransform>
            </VisualBrush>
        </Rectangle.Fill>

        <Rectangle.OpacityMask>
            <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                <GradientStop Color="#FF000000" Offset="0.0" />
                <GradientStop Color="#33000000" Offset="0.5" />
                <GradientStop Color="#00000000" Offset="0.75" />
            </LinearGradientBrush>
        </Rectangle.OpacityMask>

        <Rectangle.Effect>
            <BlurEffect Radius="1.5" />
        </Rectangle.Effect>

    </Rectangle>
</StackPanel>

Codebasiertes Beispiel

Das folgende Beispiel verwendet VisualBrush, um eine Spiegelung von Border zu erstellen, die mehrere Elemente enthält. Dieser Code wird im Window.Loaded Ereignishandler ausgeführt:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var container = new StackPanel();
    container.Height = 400;
    container.Margin = new Thickness(25);

    // Visual Element that will be reflected
    var visualElement = new Border
    {
        Width = 400,
        Background = new LinearGradientBrush(
                                    (Color)ColorConverter.ConvertFromString("#CCCCFF"),
                                    Colors.White,
                                    new Point(0.0, 0.5),
                                    new Point(1.0, 0.5))
    };

    // Stack panel inside parent border
    {
        var visualElementChild1 = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Margin = new Thickness(10)
        };

        // Stack panel content
        {
            var paragraphContent = new TextBlock
            {
                Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\nSuspendisse vel ante. Donec luctus tortor sit amet est.\nNullam pulvinar odio et wisi.\nPellentesque quis magna. Sed pellentesque.",
                Width = 200,
                Margin = new Thickness(10),
                TextWrapping = TextWrapping.Wrap
            };

            var ellipsePanel = new StackPanel();
            ellipsePanel.Children.Add(new Ellipse() { Margin = new Thickness(10), Height = 50, Width = 50, Fill = Brushes.Black });
            ellipsePanel.Children.Add(new Ellipse() { Margin = new Thickness(10), Height = 50, Width = 50, Fill = Brushes.Purple });

            // Add to parent
            visualElementChild1.Children.Add(paragraphContent);
            visualElementChild1.Children.Add(ellipsePanel);
        }

        // Add to parent
        visualElement.Child = visualElementChild1;
    }

    // Add visual to reflect to container
    container.Children.Add(visualElement);

    // Line separator
    container.Children.Add(new Rectangle() { Height = 1, Fill = Brushes.Gray, HorizontalAlignment = HorizontalAlignment.Stretch });

    // Reflection
    Rectangle reflection = new Rectangle();

    reflection.DataContext = visualElement;
    reflection.SetBinding(Rectangle.WidthProperty, "ActualWidth");
    reflection.SetBinding(Rectangle.HeightProperty, "ActualHeight");

    // Create the reflection effect
    var transform = new TransformGroup();
    transform.Children.Add(new ScaleTransform(1, -1));
    transform.Children.Add(new TranslateTransform(0, 1));

    var reflectedBrush = new VisualBrush();
    reflectedBrush.RelativeTransform = transform;
    reflectedBrush.Opacity = 0.75;
    reflectedBrush.Stretch = Stretch.None;
    reflectedBrush.Visual = visualElement;

    // Add the reflection effect
    reflection.Fill = reflectedBrush;

    reflection.OpacityMask = new LinearGradientBrush(
                                new GradientStopCollection(new[]
                                    {
                                        new GradientStop((Color)ColorConverter.ConvertFromString("#FF000000"), 0.0),
                                        new GradientStop((Color)ColorConverter.ConvertFromString("#33000000"), 0.5),
                                        new GradientStop((Color)ColorConverter.ConvertFromString("#00000000"), 0.75)
                                    }),
                                new Point(0.5, 0),
                                new Point(0.5, 1));

    reflection.Effect = new BlurEffect() { Radius = 1.5 };

    // Add the reflection to the container
    container.Children.Add(reflection);

    // Set the container as the content of this window
    Content = container;
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
    Dim container As New StackPanel With {.Height = 400, .Margin = New Thickness(25)}

    ' Visual Element that will be reflected
    Dim visualElement As New Border With {
        .Width = 400,
        .Background = New LinearGradientBrush(
                                        ColorConverter.ConvertFromString("#CCCCFF"),
                                        Colors.White,
                                        New Point(0.0, 0.5),
                                        New Point(1.0, 0.5))
    }

    ' Stack panel inside parent border
    Dim visualElementChild1 As New StackPanel With {
        .Orientation = Orientation.Horizontal,
        .Margin = New Thickness(10)
    }

    ' Stack panel content
    Dim paragraphContent As New TextBlock With {
        .Text = $"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.{vbNewLine}Suspendisse vel ante. Donec luctus tortor sit amet est.{vbNewLine}Nullam pulvinar odio et wisi.{vbNewLine}Pellentesque quis magna. Sed pellentesque.",
        .Width = 200,
        .Margin = New Thickness(10),
        .TextWrapping = TextWrapping.Wrap
    }

    Dim ellipsePanel = New StackPanel
    ellipsePanel.Children.Add(New Ellipse() With {.Margin = New Thickness(10), .Height = 50, .Width = 50, .Fill = Brushes.Black})
    ellipsePanel.Children.Add(New Ellipse() With {.Margin = New Thickness(10), .Height = 50, .Width = 50, .Fill = Brushes.Purple})

    ' Add stack panel content
    visualElementChild1.Children.Add(paragraphContent)
    visualElementChild1.Children.Add(ellipsePanel)

    ' Add stack panel to border
    visualElement.Child = visualElementChild1

    ' Add visual to reflect to container
    container.Children.Add(visualElement)

    ' Line separator
    container.Children.Add(New Rectangle() With {.Height = 1, .Fill = Brushes.Gray, .HorizontalAlignment = HorizontalAlignment.Stretch})

    ' Reflection
    Dim reflection As New Rectangle

    reflection.DataContext = visualElement
    reflection.SetBinding(Rectangle.WidthProperty, "ActualWidth")
    reflection.SetBinding(Rectangle.HeightProperty, "ActualHeight")

    ' Create the reflection effect
    Dim Transform = New TransformGroup
    Transform.Children.Add(New ScaleTransform(1, -1))
    Transform.Children.Add(New TranslateTransform(0, 1))

    Dim reflectedBrush As New VisualBrush With {
        .RelativeTransform = Transform,
        .Opacity = 0.75,
        .Stretch = Stretch.None,
        .Visual = visualElement
    }

    ' Add the reflection effect
    reflection.Fill = reflectedBrush

    reflection.OpacityMask = New LinearGradientBrush(
                                    New GradientStopCollection(
                                        {
                                            New GradientStop(ColorConverter.ConvertFromString("#FF000000"), 0.0),
                                            New GradientStop(ColorConverter.ConvertFromString("#33000000"), 0.5),
                                            New GradientStop(ColorConverter.ConvertFromString("#00000000"), 0.75)
                                        }),
                                    New Point(0.5, 0),
                                    New Point(0.5, 1))

    reflection.Effect = New BlurEffect() With {.Radius = 1.5}

    ' Add the reflection to the container
    container.Children.Add(reflection)

    ' Set the container as the content of this window
    Content = container
End Sub

Siehe auch