Wednesday, July 27, 2016

How to capture screenshot of WPF application?


In WPF application you can easily capture screen of your WPF window. In this article, I will show you how to take screenshot of full content of window.

Sometimes you need to capture all content of your window in WPF application as screenshot. You can do it via Window screen capture (using Print Screen button) but your application has large content and has scrollbar so the content is not visible and not captured via Windows print screen. In such scenario you can use below sample code to capture WPF window with full content. See below code snippet.

XAML
<Window x:Class="ScreenCaptureDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ScreenCaptureDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <ScrollViewer Name="scrollViewer">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="50" />
                <RowDefinition Height="450"/>
                <RowDefinition Height="50" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Button Content="Capture Screen"
                Grid.Row="1"
                HorizontalAlignment="Center"
                Width="150" Height="50" Click="Button_Click"  />
            <TextBlock Text="Top Left Content"
                   Grid.Row="0"
                   HorizontalAlignment="Left"></TextBlock>
            <TextBlock Text="Top Rigth Content"
                   Grid.Row="0"
                   HorizontalAlignment="Right"></TextBlock>
            <TextBlock Text="Bottom Left Content"
                   Grid.Row="2"
                   HorizontalAlignment="Left"></TextBlock>
            <TextBlock Text="Bottom Rigth Content"
                   Grid.Row="2"
                   HorizontalAlignment="Right" ></TextBlock>
        </Grid>
    </ScrollViewer>
</Window>

Code
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        //Set scrollviewer's Content property as UI element to capture full content
        UIElement element = scrollViewer.Content as UIElement;
        Uri path = new Uri(@"d:\temp\screenshot.png");
        CaptureScreen(element, path);
    }
    public void CaptureScreen(UIElement source, Uri destination)
    {
        try
        {
            double Height, renderHeight, Width, renderWidth;

            Height =  renderHeight = source.RenderSize.Height;
            Width =  renderWidth = source.RenderSize.Width;

            //Specification for target bitmap like width/height pixel etc.
            RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Pbgra32);
            //creates Visual Brush of UIElement
            VisualBrush visualBrush = new VisualBrush(source);

            DrawingVisual drawingVisual = new DrawingVisual();
            using (DrawingContext drawingContext = drawingVisual.RenderOpen())
            {
                //draws image of element
                drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(0, 0), new Point(Width, Height)));
            }
            //renders image
            renderTarget.Render(drawingVisual);

            //PNG encoder for creating PNG file
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(renderTarget));
            using (FileStream stream = new FileStream(destination.LocalPath, FileMode.Create, FileAccess.Write))
            {
                encoder.Save(stream);
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
    }
}

Output –


Generated PNG File –



As you can see in above example, MainWindow has a scrollbar and has some more content which is not visible currently on window. When you click on Capture Screen button it will capture full content of MainWindow and shows full content in generated file as per above image.

I hope you liked this article. Please leave your feedback in comments below.

See Also –

Wednesday, July 20, 2016

Bridge Pattern


Bridge pattern acts as an intermediary between two interfaces. Bridge Pattern falls under structural pattern of GOF (Gang of Four) pattern.

When to use –


Bridge pattern can be used to keep an abstraction separate from its implementation so you can change both abstraction and implementation independently without changing the client code.

Major components of Bridge pattern –


Abstraction – This is an abstract class provides abstraction to the clients.
Refined Abstraction – This class will implement the abstract class.
Implementer – This interface will act as bridge between abstraction and implementer classes and also define common functionality of implementer.
Concrete Implementer – Implements the implementer interface and defines its concrete implementation.

Let’s have a look on below code demonstrating bridge pattern.

Code –
//abstraction
public abstract class Switch
{
    public abstract void TurnOn();
    public abstract void TurnOff();
    protected IDevice device;
}

//refined abstraction
public class RemoteControl : Switch
{
    IDevice myDevice;
    public RemoteControl(IDevice device)
    {
        myDevice = device;
    }
    public override void TurnOn()
    {
        myDevice.TurnOn("Remote Control");
    }

    public override void TurnOff()
    {
        myDevice.TurnOff("Remote Control");
    }
}
//refined abstraction
public class ManualSwitchBoard : Switch
{
    IDevice myDevice;
    public ManualSwitchBoard(IDevice device)
    {
        myDevice = device;
    }
    public override void TurnOff()
    {
        myDevice.TurnOff("Manual Switch Board");
    }

    public override void TurnOn()
    {
        myDevice.TurnOn("Manual Switch Board");
    }
}
   
//implementer - Bridge interface
public interface IDevice
{
    void TurnOn(string input);
    void TurnOff(string input);
}
//concrete implementer
public class TV : IDevice
{
    public void TurnOff(string input)
    {
        Console.WriteLine("Turning off TV via {0}", input);
    }

    public void TurnOn(string input)
    {
        Console.WriteLine("Turning on TV via {0}", input);
    }
}
//concrete implementer
public class Fan : IDevice
{
    public void TurnOn(string input)
    {
        Console.WriteLine("Turning on Fan via {0}", input);
    }

    public void TurnOff(string input)
    {
        Console.WriteLine("Turning off Fan via {0}", input);
    }
}
//client
class Program
{
    static void Main(string[] args)
    {
        //Implementation objects
        IDevice TV = new TV();
        IDevice Fan = new Fan();

        //abstraction objects
        Switch TVSwitch = new RemoteControl(TV);
        Switch FanSwitch = new RemoteControl(Fan);

        //client calls abstration object methods to achieve functionality
        TVSwitch.TurnOn();
        FanSwitch.TurnOn();
        TVSwitch.TurnOff();
        FanSwitch.TurnOff();

        TVSwitch = new ManualSwitchBoard(TV);
        TVSwitch.TurnOn();
        TVSwitch.TurnOff();

        Console.ReadLine();
    }
}

Output –



Above example provides multiple ways to turn on and turn off multiple devices. You can add as many devices as you want and you can also implement more methods to turn on and turn off devices. As per above example, Switch is abstract class and inherited by multiple classes and IDevice is an interface and act as Bridge and multiple devices implemented IDevice interface to achieve implementation part of how device work. Client needs to call only abstraction objects to achieve its functionality. As per above code, TV can be turn on or off via remote control or manually via switch board. If TV/Fan turning on/off mechanism changed then it won’t impact client code.

Advantages –

  • Abstraction and implementation can be changed independently.
  • Abstraction and implementer hierarchies can be extended independently.
  • Hides implementation details from Client.

Difference between Adapter Pattern and Bridge Pattern –


Adapter Pattern
Bridge Pattern
Adapter pattern used to work with two incompatible interfaces
Bridge pattern provides multiple ways to design different components with multiple implementation. It allows to change abstraction and implementation separately.
Adapter pattern can be used on already designed objects.
Bridge pattern can be used on objects at the time of design.


I hope this article helps you to know more about Bridge Pattern. Please leave your feedback in comments below.


References –

See Also –