Показать изображение из базы данных в окне изображения каждого пользовательского элемента управления?

Код пользовательского контроля:

    private string lastName;
    public string LastName
    {
        get { return lastName; }
        set
        {
            lastName = value;
            textBox1.Text = value;
        }
    }

Код формы:

        using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString.ConnectionString))
        {
            myDatabaseConnection.Open();
            using (SqlCommand SqlCommand = new SqlCommand("Select LastName, Image from Employee", myDatabaseConnection))

            {



                int i = 0;
                SqlDataReader DR1 = SqlCommand.ExecuteReader();
                while (DR1.Read())
                {
                    i++;
                    UserControl2 usercontrol = new UserControl2();
                    usercontrol.Tag = i;
                    usercontrol.LastName = (string)DR1["LastName"];
                    flowLayoutPanel1.Controls.Add(usercontrol);
                }


            }
        }

С помощью приведенного выше кода я могу показать каждую фамилию из базы данных в текстовом поле каждого пользовательского элемента управления. Как показать изображение из базы данных в окне изображения каждого пользователя?

Вот как я отображаю одно изображение из базы данных:

        using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString.ConnectionString))
        {
            myDatabaseConnection.Open();
            using (SqlCommand SqlCommand = new SqlCommand("Select LastName, Image from Employee where ID = @a", myDatabaseConnection))
            {
                SqlCommand.Parameters.AddWithValue("@a", textBox1.Text);
                DataSet DS = new DataSet();
                SqlDataAdapter da = new SqlDataAdapter(SqlCommand);
                da.Fill(DS, "Images");
                var imagesTable = DS.Tables["Images"];
                var imagesRows = imagesTable.Rows;
                var count = imagesRows.Count;

                if (count <= 0)
                    return;
                var imageColumnValue =
                    imagesRows[count - 1]["Image"];
                if (imageColumnValue == DBNull.Value)
                    return;

                var data = (Byte[])imageColumnValue;
                using (var stream = new MemoryStream(data))
                {
                    pictureBox1.Image = Image.FromStream(stream);
                }

            }
        }  

person Karlx Swanovski    schedule 05.06.2013    source источник


Ответы (3)


Для одновременного доступа к нескольким элементам управления (PictureBox в вашем случае) используйте цикл foreach.

foreach (Control control in this.Controls)
{
    if (control is PictureBox)
    {
        PictureBox pic = (PictureBox)control;
        pic.Image = Image.FromStream(stream); //something similar, this will only load the same image to every PictureBox
    }
}
person SysGen    schedule 05.06.2013

Сделайте перегрузку для вашего конструктора UserControl, чтобы получить как фамилию, так и байты изображения. Затем вы можете сделать это в своем цикле:

            while (DR1.Read())
            {
                i++;
                UserControl2 usercontrol = new UserControl2((string)DR1["LastName"], (Byte[])DR1["Image"]);
                usercontrol.Tag = i;
                flowLayoutPanel1.Controls.Add(usercontrol);
            }

Вот обновленный UserControl (с кодом InvokeOnClick() из вашего другого вопроса). Обратите внимание в новом конструкторе, как мы создаем изображение из байтов и присваиваем его PictureBox:

public partial class UserControl2 : UserControl
{

    private string lastName;
    public string LastName
    {
        get { return lastName; }
        set
        {
            lastName = value;
            textBox1.Text = value;
        }
    }

    public UserControl2(string LastName, byte[] data)
    {
        InitializeComponent();
        WireAllControls(this);

        this.LastName = LastName;
        try
        {
            using (var stream = new System.IO.MemoryStream(data))
            {
                pictureBox1.Image = Image.FromStream(stream);
            }
        }
        catch (Exception)
        {
            MessageBox.Show("Error Loading Image for " + LastName);
        }
    }

    public UserControl2()
    {
        InitializeComponent();
        WireAllControls(this);
    }

    private void WireAllControls(Control cont)
    {
        foreach (Control ctl in cont.Controls)
        {
            ctl.Click += ctl_Click;
            if (ctl.HasChildren)
            {
                WireAllControls(ctl);
            }
        }
    }

    private void ctl_Click(object sender, EventArgs e)
    {
        this.InvokeOnClick(this, EventArgs.Empty); 
    }

}
person Idle_Mind    schedule 05.06.2013
comment
Не обрабатывал нулевые значения. Но все равно спасибо за это специально для wirecontrols. :) - person Karlx Swanovski; 05.06.2013
comment
Достаточно легко заранее проверить значение null. Вы можете создать другую перегрузку, которая принимает LastName только в том случае, если нет связанного изображения.... - person Idle_Mind; 05.06.2013

Код пользовательского контроля:

    public void showpictures()
    {
        {
            using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString.ConnectionString))
            {
                myDatabaseConnection.Open();
                using (SqlCommand SqlCommand = new SqlCommand("Select LastName, Image from Employee where LastName = @a", myDatabaseConnection))
                {

                    SqlCommand.Parameters.AddWithValue("@a", textBox1.Text);
                    DataSet DS = new DataSet();
                    SqlDataAdapter da = new SqlDataAdapter(SqlCommand);
                    da.Fill(DS, "Images");
                    var imagesTable = DS.Tables["Images"];
                    var imagesRows = imagesTable.Rows;
                    var count = imagesRows.Count;

                    if (count <= 0)
                        return;
                    var imageColumnValue =
                        imagesRows[count - 1]["Image"];
                    if (imageColumnValue == DBNull.Value)
                        return;

                    var data = (Byte[])imageColumnValue;
                    using (var stream = new MemoryStream(data))
                    {
                        pictureBox1.Image = Image.FromStream(stream);
                    }


                }
            }
        }
    }

Форма

            while (DR1.Read())
            {
                i++;
                UserControl2 usercontrol = new UserControl2();
                usercontrol.Tag = i;
                usercontrol.LastName = (string)DR1["LastName"];
                usercontrol.showpictures();
                flowLayoutPanel1.Controls.Add(usercontrol);
            }
person Karlx Swanovski    schedule 05.06.2013