Monday, March 12, 2012

How to copy a row in a Dataview based on user selection?

I have a datatable that I'm displaying in a Winform Datagrid via a
DataView, and I want the user to be able to right-click on any of the rows
and select a "copy row" command from a context menu. Then I need to make
the copy happen.
I've got the context menu up and responding appropriately, but I'm having
difficulty dealing with the copying:
Firstly, how do I identify what row the user wants to copy?
Second, how do I make a copy of the row? There is no "Clone" method for
a row. Do I need to do an element-by-element copy of the row? And if so,
can I do this with an enumerator or must I use column names?
I've been struggling with this for a half a day; I'd sure appreciate any
help.
--
MichaelMichael,
To find the current dataRow try
DataView dataView = (DataView)((CurrencyManager)
dataGrid1.BindingContext[ dataGrid1.DataSource, dataGrid1.DataMember
]).List;
DataRow dataRow = dataView[ dataGrid1.CurrentRowIndex ].Row;
To copy the row into another dataTable (with the same structure) try
destinationTable.Rows.Add(dataRow.ItemArray);
All the Best,
Phil.
"Michael Kellogg" wrote:
> I have a datatable that I'm displaying in a Winform Datagrid via a
> DataView, and I want the user to be able to right-click on any of the rows
> and select a "copy row" command from a context menu. Then I need to make
> the copy happen.
> I've got the context menu up and responding appropriately, but I'm having
> difficulty dealing with the copying:
> Firstly, how do I identify what row the user wants to copy?
> Second, how do I make a copy of the row? There is no "Clone" method for
> a row. Do I need to do an element-by-element copy of the row? And if so,
> can I do this with an enumerator or must I use column names?
>
> I've been struggling with this for a half a day; I'd sure appreciate any
> help.
> --
> Michael
>
<PhilWilliams@.discussions.microsoft.com> wrote:
> Michael,
> To find the current dataRow try
> DataView dataView = (DataView)((CurrencyManager)
dataGrid1.BindingContext [dataGrid1.DataSource,
dataGrid1.DataMember]).List;
> DataRow dataRow = dataView[ dataGrid1.CurrentRowIndex ].Row;
> To copy the row into another dataTable (with the same structure) try
> destinationTable.Rows.Add(dataRow.ItemArray);
> All the Best,
> Phil.
Thanks for the help, Phil. I'm still trying to understand exactly what
you're doing, here. I've never really understood BindingManagerBase
objects and their function. I like the way you added a copy of a row
without really cloning it; I would not have thought of that.
One issue I'm having is that, when capturing the right-click that brings
up the context menu, if you click on the row itself (the technical term
escapes me; the little box on the left side of a row), the
CurrentRowIndex property does NOT seem to update with that row. You have
to actually click on a cell inside the row. Consequently, the row
returned is wrong. I tried doing a SELECT on the row identified in the
MouseDown event handler (where the use of HitTest will give me the
correct row index), but this doesn't seem to work, either. Is there a
way to "activate" a row so the CurrentRowIndex property is guaranteed to
be right?
Thanks again for the help.
MK
Michael,
In contextMenu_Popup, try
DataGrid.HitTestInfo hti = dataGrid1.HitTest(
dataGrid1.PointToClient(Control.MousePosition));
if (hti.Row != -1)
{
DataView dataView = (DataView)((CurrencyManager)dataGrid1.BindingContext[
dataGrid1.DataSource, dataGrid1.DataMember ]).List;
DataRow dataRow = dataView[ hti.Row ].Row;
}
Cheers,
Phil.
"Michael Kellogg" wrote:
> <PhilWilliams@.discussions.microsoft.com> wrote:
> > Michael,
> > To find the current dataRow try
> >
> > DataView dataView = (DataView)((CurrencyManager)
> dataGrid1.BindingContext [dataGrid1.DataSource,
> dataGrid1.DataMember]).List;
> > DataRow dataRow = dataView[ dataGrid1.CurrentRowIndex ].Row;
> >
> > To copy the row into another dataTable (with the same structure) try
> > destinationTable.Rows.Add(dataRow.ItemArray);
> >
> > All the Best,
> > Phil.
>
> Thanks for the help, Phil. I'm still trying to understand exactly what
> you're doing, here. I've never really understood BindingManagerBase
> objects and their function. I like the way you added a copy of a row
> without really cloning it; I would not have thought of that.
> One issue I'm having is that, when capturing the right-click that brings
> up the context menu, if you click on the row itself (the technical term
> escapes me; the little box on the left side of a row), the
> CurrentRowIndex property does NOT seem to update with that row. You have
> to actually click on a cell inside the row. Consequently, the row
> returned is wrong. I tried doing a SELECT on the row identified in the
> MouseDown event handler (where the use of HitTest will give me the
> correct row index), but this doesn't seem to work, either. Is there a
> way to "activate" a row so the CurrentRowIndex property is guaranteed to
> be right?
> Thanks again for the help.
> MK
>
"=?Utf-8?B?UGhpbCBXaWxsaWFtcw==?="
<PhilWilliams@.discussions.microsoft.com> wrote:
> Michael,
> In contextMenu_Popup, try
> DataGrid.HitTestInfo hti = dataGrid1.HitTest(
> dataGrid1.PointToClient(Control.MousePosition));
> if (hti.Row != -1)
> {
> DataView dataView => (DataView)((CurrencyManager)dataGrid1.BindingContext[
> dataGrid1.DataSource, dataGrid1.DataMember ]).List;
> DataRow dataRow = dataView[ hti.Row ].Row;
> }
That is very clever; I like it. Any chance I can do something like this
in the MenuItem CLICK handler instead (obviously the mouse will have
moved by the time I select a context menu item)? I can get the row using
your method either in the POPUP, as you suggest, or in the datagrid CLICK
handler, as well. Then my thought was to stash the row number in a
member variable and use it in the MenuItem CLICK handler. However, this
didn't seem so elegant to me and I thought it'd be nice to actually
determine the row inside the handler. Am I obsessing?
--
Michael
Michael,
Add the following lines
private int clickedRow = -1;
.
.
.
private void contextMenu_Popup(object sender, System.EventArgs e)
{
DataGrid.HitTestInfo hti = dataGrid1.HitTest(
dataGrid1.PointToClient(Control.MousePosition));
clickedRow = hti.Row;
menuItemCopyRow.Enabled = clickedRow != -1;
}
private void menuItemCopyRow_Click(object sender, System.EventArgs e)
{
if (clickedRow == -1) return;
DataView dataView = (DataView)((CurrencyManager)dataGrid1.BindingContext[
dataGrid1.DataSource, dataGrid1.DataMember ]).List;
DataRow dataRow = dataView[ clickedRow ].Row;
}
All the best,
Phil.
> >
> > if (hti.Row != -1)
"Michael Kellogg" wrote:
> "=?Utf-8?B?UGhpbCBXaWxsaWFtcw==?="
> <PhilWilliams@.discussions.microsoft.com> wrote:
> > Michael,
> > In contextMenu_Popup, try
> >
> > DataGrid.HitTestInfo hti = dataGrid1.HitTest(
> > dataGrid1.PointToClient(Control.MousePosition));
> >
> > if (hti.Row != -1)
> > {
> > DataView dataView => > (DataView)((CurrencyManager)dataGrid1.BindingContext[
> > dataGrid1.DataSource, dataGrid1.DataMember ]).List;
> > DataRow dataRow = dataView[ hti.Row ].Row;
> > }
> That is very clever; I like it. Any chance I can do something like this
> in the MenuItem CLICK handler instead (obviously the mouse will have
> moved by the time I select a context menu item)? I can get the row using
> your method either in the POPUP, as you suggest, or in the datagrid CLICK
> handler, as well. Then my thought was to stash the row number in a
> member variable and use it in the MenuItem CLICK handler. However, this
> didn't seem so elegant to me and I thought it'd be nice to actually
> determine the row inside the handler. Am I obsessing?
> --
> Michael
>
<PhilWilliams@.discussions.microsoft.com> wrote:
> Michael,
> Add the following lines
> private int clickedRow = -1;
> .
> .
> .
> private void contextMenu_Popup(object sender, System.EventArgs e)
> {
> DataGrid.HitTestInfo hti = dataGrid1.HitTest(
> dataGrid1.PointToClient(Control.MousePosition));
> clickedRow = hti.Row;
> menuItemCopyRow.Enabled = clickedRow != -1;
> }
> private void menuItemCopyRow_Click(object sender, System.EventArgs e)
> {
> if (clickedRow == -1) return;
> DataView dataView => (DataView)((CurrencyManager)dataGrid1.BindingContext[
> dataGrid1.DataSource, dataGrid1.DataMember ]).List;
> DataRow dataRow = dataView[ clickedRow ].Row;
> }
> All the best,
> Phil.
Thanks, Phil!
-mk

Labels: , , , , , , , , , , , , , ,

How to convert strings yymmdd (example: 060120) into regular dates (example: 01/20/06)?

I just want to do this for displaying the data using a gridview. I am working with VB.NET.

The dates need to be saved as they are (strings = yymmdd. example: 060911) so I do not want to save how the are saved in the SQL database.

But I want to display them using the gridview in the standard date format ('mm/dd/yyyy' or 'mm/dd/yy') so I will need to convert them.


I would like to know which would be a nice way to accomplish this, thanks for any suggestions.

another thing i would like to know how to do is to convert another field from the same gridview from string: (example: '2295' into formated amounts (example: $22.95) I do not care wether they are numeric or strings, because I just want it for displaying the data in the gridview. But also these values are saved without the decimal point, for example 10099, should be converted to $100.99 or 150089 should become $1,500.89

Thanks for suggestions.

remember I do not want to change or save this data into the database, because it is supposed to be saved as it is. But I do want to be able to show the user the data in the appropiate format.

The thing is that I do not know how or where to write the code to tell the gridview to convert it how I want it.

This will convert your date to a DateTime object

DateTime.ParseExact("060708","yymmdd", System.Globalization.CultureInfo.CurrentCulture ,System.Globalization.DateTimeStyles.None)

You can handle the RowDataBound event find the label you are displaying it in and set it to something like

mylabel.Text = DateTime.ParseExact("060708","yymmdd", System.Globalization.CultureInfo.CurrentCulture ,System.Globalization.DateTimeStyles.None).ToString("mm/dd/yyy")


I need help doing the rowdatabound for doing that formating

Protected Sub GridView1_RowDataBound(ByVal senderAs Object,ByVal eAs System.Web.UI.WebControls.GridViewRowEventArgs)Handles GridView1.RowDataBoundTry If e.Row.RowType = DataControlRowType.DataRowThen Dim DollarAmountAs Label =CType(e.Row.FindControl("Label"), Label)
'Here I want to format the current string.text attribute. (how can i do it?)End If Catch End Try End Sub

You can try the solution above;

dim temp as string= DollarAmount.Text

DollarAmount.Text = DateTime.ParseExact(temp,"yymmdd", System.Globalization.CultureInfo.CurrentCulture ,System.Globalization.DateTimeStyles.None).ToString("mm/dd/yyy")


Thanks,Big Smile

Labels: , , , , , , , , , , ,