简体   繁体   English

C#/ WPF从数据库检索图像并显示它们

[英]C#/WPF Retrieving images from database and displaying them

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. 我需要从数据库中检索图像的url,将其绑定到业务对象,将其转换为位图图像,然后将其映射到资源字典中。 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. 该数据库由一个表组成,该表具有三列:id,name和url。 It is the SQL CE 3.5 local database. 它是SQL CE 3.5本地数据库。 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. 在XAML的资源字典中,我有图像控件。 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. 代码是一团糟,我敢肯定,有一种更简单的方法可以从数据库中检索图像的URL,并将其映射到资源字典中。

--- 1st try, ignore until '2nd try' --- Do not put the Image controls in the resource dictionary. ---第一次尝试,请忽略,直到“第二次尝试”为止---不要将Image控件放入资源字典中。

If you have a fixed number of images, put them directly in your Window. 如果您有固定数量的图像,请将其直接放在窗口中。 Eg: 例如:

<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. 然后,设置一个具有属性Image1和Image2的类,该类映射到来自DB的图像,并将该类的初始化实例设置为Window的DataContext。

More realistically, you have a variable number of images. 实际上,您拥有可变数量的图像。 The XAML becomes: XAML变为:

<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. 并将DataContext设置为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. 在Toolbox类中似乎。 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. 我在MSDN文档中找不到它,因此它看起来像自定义的,这很好,因为可以从中获取此信息的OnApplyTemplate方法。 If you can't modify this class, you can call ApplyTemplate() to be sure that the template is in place. 如果您不能修改此类,则可以调用ApplyTemplate()以确保模板已就位。

Now you can use VisualTreeHelper.GetChild to look at the child controls in the template, in order to find the images of interest. 现在,您可以使用VisualTreeHelper.GetChild来查看模板中的子控件,以便找到感兴趣的图像。 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. 找到图像后,您可以根据需要设置其属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM