[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1580
  • Last Modified:

Update DataGridView image column

Hello experts,

I'm working with .NET 2.0 and using the imageColumn in a DataGridView.  if I upload an image to the database initially, then the column easily displays the image.  However, there doesn't seem to be any runtime support if I want to allow the user to choose an image and insert it into the datagrid column at runtime.  

As an example, I have a grid which contains 3 columns: ID, Name, and Image.  At runtime, both ID and name are editable via a textbox, but there is no way to change the image column.  What I am looking for is some sort of solution to allow the user to update the image column as well (simply, and easily, like using a textbox or an OpenFile dialog ).  Any ideas how to best implement this solution?

Thanks
0
TLevin10
Asked:
TLevin10
  • 5
  • 4
1 Solution
 
Bob LearnedCommented:
>>if I upload an image to the database initially
How are you doing this?

Bob
0
 
TLevin10Author Commented:
I wrote a small script which takes an image file and assigns it to the cell in question.  its a fairly simple script which takes a dataset and just manually assigns images based on the "Name" column of each row (the data table in question is a series of "categories" for a larger application, since I'm only populating a few values initially, this isn't a problem, but I want the user to be able to assign an infinite number of categories once the application disseminates).

I know I can extend this script by creating a dialog which allows the user to select an image and then assigning that image to a column (I would call the dialog from a context menu attached to the DataGridView) but I am hoping that maybe there is an easier solution than performing all the actions myself.  As an example, maybe there is a way to access the built-in VS2005 "Image Select" dialog to return an image, so I don't write the entire solution myself?
0
 
Bob LearnedCommented:
Confusion abounds:

1) Small script?

2) "Image Select" dialog?

Bob

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
TLevin10Author Commented:
Hi Bob,

Sorry for the confusion.

(1)  The "small script" I'm talking about is just a foreach loop:

Load the dataset from the database and attach to the dataSource of the grid...

Run this little script:

            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                string name = row.Cells["NameColumn"].Value.ToString();

                if (name == "Stop")
                    row.Cells["ImageColumn"].Value = imageList1.Images[0];
                else if (name == "Go")
                    row.Cells["ImageColumn"].Value = imageList1.Images[1];
                else if ...etc.
            }

Save the dataset back the database...etc.

This is clearly a skinned out version, but its the basic premise for what I'm doing.  When I talk about extending the script, I mean allowing the user to select an image when they attempt to "edit" an image cell, rather than assigning it from an imageList and a for loop...

(2) When I mention the "Image Select" dialog I mean the dialog which VS2005 calls up when you use the property grid to edit the image for an object (such as a picturebox) which allows you to select an image from the resources file or to import from a file.  

Hopefully that clarifies what I am talking about?
0
 
Bob LearnedCommented:
1) You can force the Image cell to edit, but I don't know of a specific way.

2) You could add a right-click ContextMenuStrip to the cell.

3) Here is a prototype form to show what I mean:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, System.EventArgs e)
    {

        DataGridViewTextBoxColumn nameColumn = new DataGridViewTextBoxColumn();
        nameColumn.HeaderText = "File Name";
        this.gridImages.Columns.Add(nameColumn);

        DataGridViewImageColumn imageColumn = new DataGridViewImageColumn();
        imageColumn.HeaderText = "Image";
        imageColumn.ContextMenuStrip = this.contextImages;
        this.gridImages.Columns.Add(imageColumn);

        this.gridImages.Rows.Add();
        this.gridImages.Rows.Add();
        this.gridImages.Rows.Add();
    }

    private void menuInsertImage_Click(object sender, EventArgs e)
    {

        OpenFileDialog dialog = new OpenFileDialog();
        dialog.InitialDirectory = @"C:\Windows\";
        dialog.Filter = "Bitmap files (*.bmp)|*.bmp";
        dialog.ShowReadOnly = false;
        dialog.ShowHelp = false;
        dialog.Title = "Select Image";

        if (dialog.ShowDialog() == DialogResult.OK)
        {
            this.gridImages[this.gridImages.CurrentCell.ColumnIndex, this.gridImages.CurrentCell.RowIndex].Value = Image.FromFile(dialog.FileName);
            this.gridImages.AutoResizeRow(this.gridImages.CurrentRow.Index);
            this.gridImages.AutoResizeColumn(this.gridImages.CurrentCell.ColumnIndex);
        }
    }

    private void gridImages_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            this.gridImages.CurrentCell = this.gridImages[e.ColumnIndex, e.RowIndex];
        }
    }

}

4) When right-clicking on the cell, that cell is set as current, and a content menu is displayed.  When you select 'Insert Image...', then any selected image is inserted into the cell, and the column and row are resized to fit the image.

Bob
0
 
TLevin10Author Commented:
So I guess that means no automatic / built-in way to enter images into the column :)

A long answer for a short question, but I hope that it can help others who run into the same question - I decided to go with a custom solution similar to what you came up with, using a method to call the OpenFileDialog from a context menu and then inserting the chosen image back into the selected cell.

It does sadden me that Microsoft didn't build some of this functionality into the DataGridView in the first place, but leaving it open does keep the solution open to endless posibilities.
0
 
TLevin10Author Commented:
Also just a note to other EE users, Bob's solution is only a partial class and doesn't include the UI components such as the DataGridView definition nor the context menu definition - the "menuInsertImage_Click" method is called from the context menu attached to the DGV.
0
 
Bob LearnedCommented:
Yeah, not used to copying/pasting code from 2005 yet :(  

Here is Form1.Designer:

partial class Form1
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container();
        this.gridImages = new System.Windows.Forms.DataGridView();
        this.contextImages = new System.Windows.Forms.ContextMenuStrip(this.components);
        this.menuInsertImage = new System.Windows.Forms.ToolStripMenuItem();
        ((System.ComponentModel.ISupportInitialize)(this.gridImages)).BeginInit();
        this.contextImages.SuspendLayout();
        this.SuspendLayout();
        //
        // gridImages
        //
        this.gridImages.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        this.gridImages.Location = new System.Drawing.Point(12, 75);
        this.gridImages.Name = "gridImages";
        this.gridImages.Size = new System.Drawing.Size(500, 307);
        this.gridImages.TabIndex = 0;
        this.gridImages.CellMouseDown += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.gridImages_CellMouseDown);
        //
        // contextImages
        //
        this.contextImages.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.menuInsertImage});
        this.contextImages.Name = "contextImages";
        this.contextImages.Size = new System.Drawing.Size(175, 26);
        //
        // menuInsertImage
        //
        this.menuInsertImage.Name = "menuInsertImage";
        this.menuInsertImage.Size = new System.Drawing.Size(174, 22);
        this.menuInsertImage.Text = "Insert Image...";
        this.menuInsertImage.Click += new System.EventHandler(this.menuInsertImage_Click);
        //
        // Form1
        //
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(550, 486);
        this.Controls.Add(this.gridImages);
        this.Name = "Form1";
        this.Text = "Form1";
        this.Load += new System.EventHandler(this.Form1_Load);
        ((System.ComponentModel.ISupportInitialize)(this.gridImages)).EndInit();
        this.contextImages.ResumeLayout(false);
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.DataGridView gridImages;
    private System.Windows.Forms.ContextMenuStrip contextImages;
    private System.Windows.Forms.ToolStripMenuItem menuInsertImage;
}
0
 
TLevin10Author Commented:
Definitely takes some getting used to :)
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now