0

I'm trying to create a snapshot/image/bitmap of an element that I can display as content in another control.

It seems the suggested way to do this is with a VisualBrush, but I can't seem to get it to create a snapshot of the current value and keep that state. When you alter the original source, the changes are applied to all the "copies" that have been made too.

I have made a simple example to show what I mean.

What I want is for the items added to the stackpanel to have the opacity that was set when they were cloned. But instead, changing the opacity on the source changes all "clones".

<StackPanel Width="200" x:Name="sp">
    <DockPanel>
        <Button Content="Clone"
                Click="OnCloneButtonClick" />
        <TextBlock Text="Value" x:Name="tb" Background="Red" />
    </DockPanel>
</StackPanel>

  private void OnCloneButtonClick(object sender, RoutedEventArgs e)
    {
        tb.Opacity -= 0.1;
        var brush = new VisualBrush(tb).CloneCurrentValue();

        sp.Children.Add(new Border() { Background = brush, Width = tb.ActualWidth, Height = tb.ActualHeight });
    }
wforl
  • 91
  • 9

1 Answers1

1

I am afraid the visual elements aren't cloned when you call CloneCurrentValue().

You will have to clone the element yourself, for example by serializing the element to XAML and then deserialize it back using the XamlWriter.Save and XamlReader.Parse methods respectively:

private void OnCloneButtonClick(object sender, RoutedEventArgs e)
{
    tb.Opacity -= 0.1;
    var brush = new VisualBrush(Clone(tb));

    sp.Children.Add(new Border() { Background = brush, Width = tb.ActualWidth, Height = tb.ActualHeight });
}

private static Visual Clone(Visual visual)
{
    string xaml = XamlWriter.Save(visual);
    return (Visual)XamlReader.Parse(xaml);
}
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Interestingly, this doesn't seem to work when you try it on an item in an itemscontrol? it will serialise the elements, but none of the properties, any ideas why that might be? – wforl Nov 05 '22 at 10:12