Jump to content
  • Advertisement
Sign in to follow this  
Subotron

[.net] OpenFileDialog in dataGridView?

This topic is 4118 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The goal I'm trying to achieve is that one column in a dataGridView (bound) works using an OpenFileDialog. To clarify, I want a '...'-button in the cell, which if clicked shows an OpenFileDialog, which in turn sets the value of the cell (to OpenFileDialog.FileName). In a propertyGrid I can easily do this by placing
[Editor( typeof( System.Windows.Forms.Design.FileNameEditor ), typeof( System.Drawing.Design.UITypeEditor ) )]
above the property However, it doesn't seem to work for the dataGridView. Is there a way to achieve a similar effect in the dataGridView? Also, I will probably use it for a textbox control as well. Thanks in advance for the help!

Share this post


Link to post
Share on other sites
Advertisement
What you are looking for is DataGridViewButtonColumn. This allows you to add buttons to any DataGridView Column.

If you have any questions about using it, let me know.
theTroll

Share this post


Link to post
Share on other sites
Thanks, but a DataGridViewButtonColumn was not what I needed. Turns out what I needed was a user control and a matching class derived from DataGridViewCell. I got it to work though :)

Share this post


Link to post
Share on other sites
Oops, still got a problem. Creating a column with cells containing my user control works fine, by setting dataGridView.Columns["File"].CellTemplate = new FileControlCell();

However, at some point I want to retrieve the FileControl (which is my user control), because it holds a value (previousValue) I'm interested in. I tried like this:

FileControlCell fileControlCell = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] as FileControlCell;
e.Value = fileControlCell.FileControl.OldValue;

e = the event args, so e.RowIndex and e.ColumnIndex point to the active cell. The code compiles fine, but fileControlCell.FileControl.OldValue (in fact all members of FileControl) are at the state the constructor gave them. OldValue is supposed to have a value (I traced it in the debugger) but it doesn't. So somehow I don't get the right FileControl (I think).

Any suggestions on how to retrieve the data I need?

Share this post


Link to post
Share on other sites
Anyone? I still can't figure it out. I found some suggestions on overriding the clone() function of the custom DataGridViewCell, but it doesn't get me anywhere. I'll post my current code just in case it's needed (I'm working on it so it might have some bad parts atm)

[source lang=c#]
public class FileControlCell : DataGridViewTextBoxCell
{
static FileControl fileControl = null;

public FileControlCell()
{
fileControl = new FileControl();
}

public override Type EditType
{
get { return typeof( FileControl ); }
}

public FileControl FileControl
{
get { return fileControl; }
set { fileControl = value; }
}

protected override Size GetPreferredSize( Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize )
{
try
{
if ( this.IsInEditMode )
return fileControl.Size;
else
return base.GetPreferredSize( graphics, cellStyle, rowIndex, constraintSize );
}
catch
{
return base.GetPreferredSize( graphics, cellStyle, rowIndex, constraintSize );
}
}

public override object Clone()
{
FileControlCell cell = base.Clone() as FileControlCell;

if (cell != null)
cell.FileControl = this.FileControl;

return cell;
}
}



[source lang=C#]
public partial class FileControl : UserControl, IDataGridViewEditingControl
{
DataGridView dataGridView = null;
int rowIndex = 0;
bool valueChanged = false;
string oldValue = null;

public FileControl()
{
InitializeComponent();

this.txtFilePath.LostFocus += new EventHandler( txtFilePath_LostFocus );
}

void txtFilePath_LostFocus( object sender, EventArgs e )
{
NotifyChange();
}

private void btnBrowse_Click(object sender, EventArgs e)
{
valueChanged = false;

if ( sfdFile.ShowDialog() == DialogResult.OK )
this.txtFilePath.Text = sfdFile.FileName;

NotifyChange();
}

private void NotifyChange()
{
if ( this.txtFilePath.Text != oldValue )
{
valueChanged = true;
dataGridView.NotifyCurrentCellDirty( true );
}
}

public string OldValue
{
get { return oldValue; }
set { oldValue = value; }
}

public void ApplyCellStyleToEditingControl( DataGridViewCellStyle dataGridViewCellStyle )
{
}

public Cursor EditingControlCursor
{
get { return Cursors.IBeam; }
}


public Cursor EditingPanelCursor
{
get { return Cursors.IBeam; }
}

public DataGridView EditingControlDataGridView
{
get { return dataGridView; }
set { dataGridView = value; }
}

public object EditingControlFormattedValue
{
get { return this.txtFilePath.Text; }
set { this.txtFilePath.Text = value.ToString(); }
}

public int EditingControlRowIndex
{
get { return rowIndex; }
set { rowIndex = value; }
}

public bool EditingControlValueChanged
{
get { return valueChanged; }
set { valueChanged = value; }
}

public bool EditingControlWantsInputKey( Keys keyData, bool dataGridViewWantsInputKey )
{
switch ( keyData )
{
case Keys.Tab:
return true;

case Keys.Home:

case Keys.End:

case Keys.Left:
if (this.txtFilePath.SelectionLength == this.txtFilePath.Text.Length)
return false;
else
return true;

case Keys.Right:
return true;

case Keys.Delete:
this.txtFilePath.Text = "";
return true;

case Keys.Enter:
NotifyChange();
return false;

default:
return false;
}
}

public object GetEditingControlFormattedValue( DataGridViewDataErrorContexts context )
{
return this.txtFilePath.Text;
}

public void PrepareEditingControlForEdit( bool selectAll )
{
if (this.dataGridView.CurrentCell.Value == null)
this.txtFilePath.Text = "";
else
this.txtFilePath.Text = this.dataGridView.CurrentCell.Value.ToString();
if (selectAll)
this.txtFilePath.SelectAll();

oldValue = this.txtFilePath.Text;
}

public bool RepositionEditingControlOnValueChange
{
get { return false; }
}
}

Share this post


Link to post
Share on other sites
This should get you on your way, well unless of course you tell me this is not what you need again.


private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
string filepath = "";
if (e.ColumnIndex == 3) /// This is the column that contains your DataGridViewButtonColumn..
{
OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() == DialogResult.OK)
{
filepath = fd.FileName;
}
MessageBox.Show(filepath);

}

}





Hope it helps..
theTroll

Share this post


Link to post
Share on other sites
hmmm that might actually work as well, it would make the custom DataGridViewCell unnecessary. Thanks a whole lot for your help, rating++ of course ;)

Share this post


Link to post
Share on other sites
By setting the column you want the ... to DataGridViewButtonColumn, it automatically makes that column buttons for you. Then you just set the Column text to "...". I would suggest locking the column to a given size that looks right for the "...", so that if they resize it doesn't resize the buttons.

theTroll

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!