Johnny Doe
Johnny Doe

Reputation: 5

Set image control source in view model Wpf

I have a view that contains an image control that is binded to this property:

   private System.Drawing.Image _sigImage;
    public System.Drawing.Image sigImage
    {
        get { return _sigImage; }
        set { _sigImage = value; RaisePropertyChanged(); }
    }

I am busy implementing a a signature pad using mvvm, and want the signature to display in the image control. However i cant get it to display.

The code for die signature pad is:

  DynamicCapture dc = new DynamicCaptureClass();
        DynamicCaptureResult res = dc.Capture(sigCtl, "Who", "Why", null, null);
        if (res == DynamicCaptureResult.DynCaptOK)
        {

            sigObj = (SigObj)sigCtl.Signature;
            sigObj.set_ExtraData("AdditionalData", "C# test: Additional data");

            try
            {
                byte[] binaryData = sigObj.RenderBitmap("sign", 200, 150, "image/png", 0.5f, 0xff0000, 0xffffff, 10.0f, 10.0f, RBFlags.RenderOutputBinary | RBFlags.RenderColor32BPP) as byte[];
                using (MemoryStream memStream = new MemoryStream(binaryData))
                {
                    System.Drawing.Image newImage = System.Drawing.Image.FromStream(memStream);

                    sigImage = newImage;

                    // work with image here. 
                    // You'll need to keep the MemoryStream open for 
                    // as long as you want to work with your new image. 
                    memStream.Dispose();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

The image is stored as a bitmap in the variable newImage.

How can i bind that image to the image control of sigImage?

Upvotes: 1

Views: 122

Answers (1)

Clemens
Clemens

Reputation: 128061

System.Drawing.Image is not an appropriate type for the Source property of an Image element. It is WinForms, not WPF.

Use System.Windows.Media.ImageSource instead

private ImageSource sigImage;

public ImageSource SigImage
{
    get { return sigImage; }
    set { sigImage = value; RaisePropertyChanged(); }
}

and assign a BitmapImage or BitmapFrame to the property, which is directly created from the MemoryStream. BitmapCacheOption.OnLoad has to be set in order to enable closing the stream immediately after decoding the bitmap.

var bitmapImage = new BitmapImage();

using (var memStream = new MemoryStream(binaryData))
{
    bitmapImage.BeginInit();
    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    bitmapImage.StreamSource = memStream;
    bitmapImage.EndInit();
}

bitmapImage.Freeze();
SigImage = bitmapImage;

The Binding would look like shown below, provided an instance of the class with the SigImage property is assigned to the DataContext of the view.

<Image Source="{Binding SigImage}"/>

Since WPF has built-in type conversion from string, Uri and byte[] to ImageSource, you may as well declare the source property as byte[]

private byte[] sigImage;

public byte[] SigImage
{
    get { return sigImage; }
    set { sigImage = value; RaisePropertyChanged(); }
}

and assign a value like

SigImage = binaryData;

without manually creating a BitmapImage or BitmapFrame, or changing the Binding.

Upvotes: 1

Related Questions