6

I have a WPF question.

I have 2 textboxes and an image control in a WPF Form. The image control has an image in it.

I want to insert the contents of each of the text boxes and the image in the 3 separate columns in an SQL database. The text boxes feed into varchar columns while the image itself is loaded into a column with datatype image.

How can I do this?

Thanks

Tom H
  • 46,766
  • 14
  • 87
  • 128
femi
  • 974
  • 2
  • 13
  • 44

5 Answers5

4

The way we do it is to store the images as blobs in the database (they're fairly small images, 4-500k, so storing them in the db shouldn't cause any perf problems), retreive them as byte arrays, and then use a ValueConverter to convert from byte[] to BitMap. The XAML for the image control looks like this:

<Image Source="{Binding Path=RawImageData, 
                        Converter={StaticResource ByteArrayToBitmapImageConverter},
                        Mode=OneWay}" />

The property we bind to in the ViewModel is simply a byte[] like this;

private byte[] _rawImageData;
public byte[] RawImageData
{
    get { return _rawImageData; }
    set
    {
        if (value != _rawImageData)
        {
            _rawImageData = value;
            NotifyPropertyChanged("RawImageData");
        }
    }
}

And then the ValueConverte looks like this;

    public class ByteArrayToBitmapImageConverter : IValueConverter
    {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {
        var rawImageData = value as byte[];
        if (rawImageData == null)
          return null;

        var bitmapImage = new System.Windows.Media.Imaging.BitmapImage();
        using (var stream = new MemoryStream(rawImageData))
        {
          bitmapImage.BeginInit();
          bitmapImage.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
          bitmapImage.CacheOption = BitmapCacheOption.Default;
          bitmapImage.StreamSource = stream;
          bitmapImage.EndInit();
        }
        return bitmapImage;
      }

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     {
       throw new NotImplementedException();
     }
   }
Kjetil Klaussen
  • 6,266
  • 1
  • 35
  • 29
1

Below a way of how to store/retrieve images in a database using Linq to SQL in WPF.

Database

It's recommended to store the images in separate tables. Create the table where to store your images,

CREATE TABLE UploadedImage(
 [ImageID] [int] IDENTITY(1,1) NOT NULL,
 [ImageName] [varchar](100) NOT NULL,
 [ImageContent] [image] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

Data access layer using Linq 2 SQL

In Visual Studio add a new item of type LINQ to SQL Classes (.dbml) and lets call it MyDataContext. Use Server Explorer in VS, connect to your database and drag the table of your images UploadedImage to the .dbml design area. Save the MyDataContext file Ctrl + S.

XAML

<TextBox x:Name="ImagePath" />
<Button x:Name="BrowseButton" Content="..." Click="BrowseButton_OnClick"/>
<Button x:Name="SaveButton" Content="Save" Click="SaveButton_OnClick"/>
<Button x:Name="LoadButton" Content="Load" Click="LoadButton_OnClick" />
<Image x:Name="MyImage" >
    <Image.Source>
        <BitmapImage UriSource="{Binding ElementName=ImagePath, Path=Text}" />
    </Image.Source>
</Image>

Code behind

private byte[] _imageBytes = null;

// Browse for an image on your computer
private void BrowseButton_OnClick(object sender, RoutedEventArgs e)
{
    var dialog = new OpenFileDialog
    {
        CheckFileExists = true,
        Multiselect = false,
        Filter = "Images (*.jpg,*.png)|*.jpg;*.png|All Files(*.*)|*.*"
    };

    if (dialog.ShowDialog() != true) { return; }

    ImagePath.Text = dialog.FileName;
    MyImage.Source = new BitmapImage(new Uri(lImagePath.Text));

    using (var fs = new FileStream(ImagePath.Text, FileMode.Open, FileAccess.Read))
    {
        _imageBytes = new byte[fs.Length];
        fs.Read(imgBytes, 0, System.Convert.ToInt32(fs.Length));
    }
}

// Save the selected image to your database
private void SaveButton_OnClick(object sender, RoutedEventArgs e)
{
    if (!String.IsNullOrEmpty(ImagePath.Text))
    {
        var db = new MyDataContext();
        var uploadedImg = new UploadedImage
        {
            ImageID = 0,
            ImageContent = _imageBytes,
            ImageName = ImagePath.Text
        };

        db.UploadedImages.InsertOnSubmit(uploadedImg);
        db.SubmitChanges();
    }
}

// Load an image from the database
private void LoadButton_OnClick(object sender, RoutedEventArgs e)
{
    // Load 1 image from the database and display it
    var db = new ImageInDatabaseDataContext();
    var img = (from el in db.UploadedImages
        select el).FirstOrDefault();


    if (img != null)
    {
        // Display the loaded image
        ImageFile.Source = new BitmapImage(new Uri(img.ImageName));
    }
}
Stacked
  • 6,892
  • 7
  • 57
  • 73
0

make 2 table ,first table contains textbox1's text[maybe "name"] ,textbox2's text[maybe "surname"] and imageId[] ,another table contains file id ,filebytes and file extentions.when you save the aforementioned information with picture. take bytes of image and extention save this. when you get the image inorder to show somewhere,you translate byte to file via its extention http://www.beansoftware.com/ASP.NET-Tutorials/Save-Read-Image-Database.aspx in here for ASP.NET but controls are generally same in .net.(textbox.Text etc.)

private void Button1_Click(object sender, System.EventArgs e)
{
 Stream img_strm = upload_file.PostedFile.InputStream;

//Retrieving the length of the file to upload
int img_len = upload_file.PostedFile.ContentLength;
//retrieving the type of the file to upload
string strtype = upload_file.PostedFile.ContentType.ToString();
string strname = txtimgname.Text.ToString();
byte[] imgdata = new byte[img_len];
int n = img_strm.Read(imgdata, 0, img_len);
int result = SaveToDB(strname, imgdata, strtype);}
ibrahimyilmaz
  • 18,331
  • 13
  • 61
  • 80
  • thanks for this...its a step in the right direction.. Are there any examples where i can use WPF data bindings to do this? how will i manage field level validations errors in the above scenario? i am using SQL Compact as the database. From what i see i have to manaually map the contents of each control to the databaase , possibly in the method SaveToDB. Is there any other neater or cleaner way to achieve my aim, possibly using collectionviewsource or LINQ TO SQL? Thanks – femi Feb 25 '10 at 12:44
  • maybe this url ll be good for you http://www.aneef.net/2009/01/16/uploading-binary-files-or-images-using-linq-to-sql/ – ibrahimyilmaz Feb 25 '10 at 15:25
0

I'm not sure how the image field type works, however, this might be useful:

Image UriSource and Data Binding

In other words, you may need to use a value converter to convert to/from your db format to your presentation (WPF) format.

Community
  • 1
  • 1
Nate
  • 30,286
  • 23
  • 113
  • 184
0

If you want to handle BitmapSource images including cases in which the images' sources are not files, then I recommend copying the pixels' buffer into an array, then storing the array + pixelformat and dimensions metadata (array and metadata can be use to recreate the image).

Danny Varod
  • 17,324
  • 5
  • 69
  • 111