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 sqldatasource to other type like dataview, dataset or datareader

Hi all,

i have got many problems with sqldatasource and dataview

--------------------------------
string ConnectionString = "Server=server;Integrated
Security=True;Database=contest;Persist Security Info=True";

string QueryString = "SELECT * FROM [members]";

System.Web.UI.WebControls.SqlDataSource SqlDataSource = new System.Web.UI.WebControls.SqlDataSource();

SqlDataSource.ConnectionString = ConnectionString;
SqlDataSource.SelectCommand = QueryString;
SqlDataSource.DataSourceMode = System.Web.UI.WebControls.SqlDataSourceMode.DataSet;

DataView dv = new DataView();

dv = (DataView)SqlDataSource;
--------------------------------

CS0030: Cannot convert type 'System.Web.UI.WebControls.SqlDataSource' to 'System.Data.DataView'

--------------------------------

i got similar problems if i use DataSet and DataReader.
SqlDataSource.DataSourceMode = System.Web.UI.WebControls.SqlDataSourceMode.DataSet;
SqlDataSource.DataSourceMode = System.Web.UI.WebControls.SqlDataSourceMode.DataReader;

--------------------------------

thx a lot.To return the DataSet from the SqlDataSource you have to use the SqlDataSource Select method. The Select method will return a DataView if the DataSourceMode of the SqlDataSource is set to System.Web.UI.WebControls.SqlDataSourceMode.DataSet.

If you set the mode to System.Web.UI.WebControls.SqlDataSourceMode.DataReader. A DataReader will be returned.
thx,
but, i dont know how to use sqldatasource as dataview after set it to dataset.
u have an example ?
thx
What is your purpose with the code? Do you only want to access a data source and get a Dataset back? If so I should recommend you to use SqlDataAdaptar:


DataSet ds = new DataSet();

using(SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Employees", myConnectionString))
{
adapter.Fill(ds);
}

If you want to use SqlDataSource for some reason, here is an example:


string ConnectionString = "Server=localhost;Integrated Security=True;Database=Northwind;User=****;password=****;";
string QueryString = "SELECT * FROM [Employees]";
System.Web.UI.WebControls.SqlDataSource SqlDataSource = new System.Web.UI.WebControls.SqlDataSource();
SqlDataSource.ConnectionString = ConnectionString;
SqlDataSource.SelectCommand = QueryString;

DataSourceSelectArguments arg = new DataSourceSelectArguments();
System.Data.DataView dv = (System.Data.DataView)SqlDataSource.Select(arg);


okay thanks, now continuing on with system.data.dataview dv = ..., how do you retrieve a value, can you finish the code for us?
Many thanks,
Asaf

Here is the thing

DataView dv ;

dv = (DataView)DsOpenOrders.Select(DataSourceSelectArguments.Empty);

dv.Sort = SortField;

return dv;

DsOpenOrders is the SqlDataSource.

THis will help you I guess.

Thanks
Suda

Labels: , , , , , , , , ,

how to convert objectdatasource to dataView?

hi there...does anyone run into a problem where the objectdatasource cannot be casting into dataview? it aleays works for me except for this time

.csDataView dv = (DataView)objSubCategoriesByUserPermissions.Select();.aspx<asp:ObjectDataSource ID="objSubCategoriesByUserPermissions" runat="server" SelectMethod="GetCategoryByUserPermissions" TypeName="MB.TheBeerHouse.BLL.Articles.Category"> <SelectParameters> <asp:QueryStringParameter Name="articleID" QueryStringField="ID" DefaultValue="-1" /> <asp:ProfileParameter Name="username" PropertyName="username" /> </SelectParameters> </asp:ObjectDataSource> <br /> <asp:SqlDataSource ID="sdcAllCategories" runat="server" ConnectionString="<%$ ConnectionStrings:ASPNETDBConnectionString%>" SelectCommand="SELECT CategoryID, Title FROM tbh_Categories WHERE (visible = 1) AND (ParentID IS NULL)"> </asp:SqlDataSource>

Unable to cast object of type 'System.Object[]' to type 'System.Data.DataView'.

Hi

ObjectDataSource.select() must return one of the types listed below:

IEnumerable

TheIEnumerable is returned by theSelect method.

DataTable

ADataView is created by using theDataTable and returned by theSelect method.

DataView

TheDataView is returned by theSelect method.

DataSet

The firstDataTable of theDataSet is extracted and aDataView is created and returned by theSelect method.

Object

The object is wrapped in a one-elementIEnumerable collection and returned by theSelect method.

Here is a similar thread that may give you clue:http://forums.asp.net/thread/1491464.aspx

For details about ObjectDataSource.select() seehttp://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.select.aspx

Hope this helps.


thank it does.

Labels: , , , , , , ,

How to convert a DataView with RowFilter to a new DataTable?

Hello,
I have this:
Dim dv As New DataView(GetUsersAsDataTable())
dv.RowFilter = "brithday >= 1970"
Dim dt As New DataTable
dt = **how to bring my rowfiltered DataView to a new DataTable** ?
When I do
dt = dv.Table
I get my original DataTable so that is unfortunatly not the solution.
Thanks for any help in advance!!
AndreasHi Andreas,
I don't think that there is a built-in way.
Do it manually in a loop, perhaps.
--
Miha Markic - RightHand .NET consulting & software development
miha at rthand com
"Andreas Klemt" <aklemt68@.hotmail.com> wrote in message
news:ufJReiBuDHA.540@.tk2msftngp13.phx.gbl...
> Hello,
> I have this:
> Dim dv As New DataView(GetUsersAsDataTable())
> dv.RowFilter = "brithday >= 1970"
> Dim dt As New DataTable
> dt = **how to bring my rowfiltered DataView to a new DataTable** ?
> When I do
> dt = dv.Table
> I get my original DataTable so that is unfortunatly not the solution.
> Thanks for any help in advance!!
> Andreas
>
>
Andreas Klemt wrote:
> Hello,
> I have this:
> Dim dv As New DataView(GetUsersAsDataTable())
> dv.RowFilter = "brithday >= 1970"
> Dim dt As New DataTable
> dt = **how to bring my rowfiltered DataView to a new DataTable** ?
> When I do
> dt = dv.Table
> I get my original DataTable so that is unfortunatly not the solution.
Why do you need it back to a DataTable? You can bind to the DataView
just as easily.

Labels: , , , , , , , ,