Konrad Reiche
Konrad Reiche

Reputation: 29493

Dynamic windows preview generation with WPF

I have many different windows and they all have a different design. The different windows are selected in a menu. The menu has screenshots of the windows in every row. I would like to find a way and automatize the following steps:

  1. make a screenshot of the window
  2. insert the picture in the new window
  3. link the click handler

So, actually my question is, whether it is possible to get the image of the yet hidden window during runtime

Upvotes: 0

Views: 294

Answers (1)

Yiğit Yener
Yiğit Yener

Reputation: 5986

This should give the idea. I have a control template for my windows. This template has a VisualTarget element that wraps all the other controls in each instance. So the code below works for me.

class ThumbnailView
{
    public Guid WindowGuid { get; set; }
    public Window ApplicationWindowInstance { get; set; }
    public Border ThumbnailVisual
    {
        get {
            return (this.ApplicationWindowInstance.
                            Template.FindName("VisualTarget", 
                            this.ApplicationWindowInstance) as Border);
        }
    }
}

<Border BorderThickness="0,0,0,0" Cursor="Hand">
    <Border.Background>
        <VisualBrush Visual="{Binding ThumbnailVisual}"/>
    </Border.Background>
</Border>


Edit: Here is something more general

ObservableCollection<WindowInstance> _windows = new ObservableCollection<WindowInstance>();

class WindowInstance
{
    public Window CurrentWindowInstance { get; set; }
    public DependencyObject CurrentVisual {
        get {
            return VisualTreeHelper.GetChild(CurrentWindowInstance, 0);
        }
    }
}

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel></StackPanel>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderThickness="0,0,0,0" Width="50" Height="50">
                <Border.Background>
                    <VisualBrush Visual="{Binding CurrentVisual}"/>
                </Border.Background>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>


Edit: Examples above are using live visual brushes which could lead to a performance breakdown. So following is the answer for frozen window thumbnails.

ObservableCollection<BitmapFrame> _windowCaptures = new ObservableCollection<BitmapFrame>();

TestWindow testWindow = new TestWindow();
RenderTargetBitmap bitmap = new RenderTargetBitmap((int)testWindow.Width, (int)testWindow.Height, 96, 96,
                                        PixelFormats.Pbgra32);
bitmap.Render((Visual)VisualTreeHelper.GetChild(testWindow, 0));
_windowCaptures.Add(BitmapFrame.Create(bitmap));

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel></StackPanel>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Height="100" Width="100" Source="{Binding}"></Image>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Upvotes: 1

Related Questions