views:

446

answers:

2

Hi, I need to retrieve the url of the image from the database, bind it to a business object, convert it into a bitmap image and map it into the resource dictionary. The resource dictionary is used as a library and I cannot change it.

The database consists of one table that has three columns: id, name, url. It is the SQL CE 3.5 local database. I want to be able to show all images at once.

What I managed to write:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Collections;
using System.Collections.ObjectModel;
using System.Windows.Media.Imaging;
using System.Windows;
using System.Windows.Media;



namespace Library.Components
{
    public class ComponentsList : ObservableCollection<Components>
    {
        public ComponentsList()
        {


            String connString = @"Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5; Data Source=local_source";

            String query = @"SELECT id, name, url FROM GraphicComponents";

            // Fill the Set with the data
            using (SqlConnection conn = new SqlConnection(connString))
            {
                try
                {
                    SqlCommand cmd = conn.CreateCommand();
                    cmd.CommandText = query;

                    conn.Open();
                    SqlDataReader rdr = cmd.ExecuteReader();
                    while (rdr.Read())
                    {

                        this.Add(new Components(rdr));

                    }
                }
                finally
                {
                    if (conn.State != ConnectionState.Closed) conn.Close();
                }
            }
        }


    }
    public class Components
    {

  int _componentID;
  string _name;
  BitmapImage _url;


  public Components(IDataRecord record)
  {
      _componentID = (int)record["id"];
      _name = (string)record["name"];
      _url = (string)record["url"];

  //Code taken from a tutorial used to convert the url into BitmapImage
    CreatePhoto((byte[])record["url"]);
  }


  void CreatePhoto(byte[] photoSource)
  {

    _url = new System.Windows.Media.Imaging.BitmapImage();
    System.IO.MemoryStream strm = new System.IO.MemoryStream();


    int offset = 78;
    strm.Write(photoSource, offset, photoSource.Length - offset);

    // Read the image into the bitmap object
    _url.BeginInit();
    _url.StreamSource = strm;
    _url.EndInit();

  }
  public int ComponentID
  {
      get { return _componentID; }
  }

  public string Name
  {
      get { return _name; }

  }

  public BitmapImage Photo
  {
      get { return _url; }
  }

    }
}

In the resource dictionary in XAML I have Images controls. The source of the image is hardcoded; but I need to retrieve it from the database.

Thanks in advance for any help. The code is a mess and I'm sure that there is a simpler way of retrieving the URLs of the images from a database and map them into the resource dictionary.

A: 

Why not use ResourceManagers?

Checkout: Nice Example on Resource Managers

LnDCobra
I have a resource dictionary in XAML that is used in another place. It looks like this:<ResourceDictionary> <Image IsHitTestVisible="False" Stretch="Fill" ToolTip="Nuclear" Source="Library/image2.png" /> <Image IsHitTestVisible="False" Stretch="Fill" ToolTip="Plus" Source="Library/image1.png" /> </ItemsControl.Items> </s:Toolbox></ResourceDictionary>As you can see, the urls are hardcoded. I need a binding here.
EVA
A: 

--- 1st try, ignore until '2nd try' --- Do not put the Image controls in the resource dictionary.

If you have a fixed number of images, put them directly in your Window. E.g.:

<Window>
   <StackPanel>
      <Image Source="{Binding Path=Image1}" />
      <Image Source="{Binding Path=Image2}" />
   </StackPanel>
</Window>

Then setup a class with the properties Image1 and Image2 mapping to the images coming from your DB and set an initialized instance of this class as the DataContext of your Window.

More realistically, you have a variable number of images. The XAML becomes:

<Window>
  <ItemsControl ItemsSource="{Binding Path=Components}">
     <ItemsControl.ItemTemplate>
       <DataTemplate>
          <Image Source="{Binding Path=Photo}" />
       </DataTemplate>
     </ItemsControl.ItemTemplate>
  <ItemsControl>
</Window>

And set the DataContext to an instance of ComponentsList.

What you could put in the Resources dictionary is the item template. --- end of 1st try ---

2nd try: After our comments exchange, the situation is that you have a template defined in the resource dictionary that you want to modify at run-time.

It is necessary to wait that the template has been applied to your control hosting the images. It seems to a Toolbox class. I can't find it in the MSDN docs, so it looks custom, which is good as there is the OnApplyTemplate method where you get this information. If you can't modify this class, you can call ApplyTemplate() to be sure that the template is in place.

Now you can use VisualTreeHelper.GetChild to look at the child controls in the template, in order to find the images of interest. In the example template, the images don't have a name attribute. If you can't have one added, you need to devise a strategy to recognize them, either by order or some other attributes, like the Tooltip.

Once an image is found, you can set its properties as you like.

Timores
Perhaps I should have provided more details. The application is used to create the diagrams out of the provided elements (from the resource dictionary). You drag and drop them, then connect them, etc. The images were put in the resources dictionary and it is very unlikely that I could change that.
EVA
If they are in the resources dictionary, why do you read them from the DB ?
Timores
The project requirement is the closest answer I can give. It is supposed to be loaded library. If I were writing it from the scratch it wouldn't be like this.
EVA
Is it even possible to use the binding in that way?
EVA
Sorry, I am lost, you have to use the resources dictionary which has hard-coded file URLs and you want the images to come from the DB. Is this correct ?
Timores
Yes, that's right.
EVA