GridView get ODS DataObjectTypeName

C

Chuck P

I am creating a control which inherits from the GridView.

I want to have an event that adds a new row to the ODS before the GridView
binds.

I was thinking of doing this:

private void AttachDataSourceEvent()
{
ObjectDataSource ds = GetDataSource() as ObjectDataSource;
if (ds != null)
{
ds.Selected += new
ObjectDataSourceStatusEventHandler(this.OnObjectDataSource_Selected);
}
}

protected void OnObjectDataSource_Selected(object sender,
ObjectDataSourceStatusEventArgs e)
{
if (m_addButtonClicked)//Add empty record for the first row to
the LIST
{
List<T> list = (List<T>)e.ReturnValue;
list.Insert(0, new T());
}
}

I think the above code will retrieve the ODS used by the GridView.
However, the code in OnObjectDataSource_Selected was from a Helper Class
that new what the ODS DataObjectType was. Now I am having trouble getting
what the object type used is. I can get the ODS
DataObjectTypeName="GridViewHelperTestObjects+TestRow"
but I don't know how to convert this type of syntax to a Type.
 
W

Walter Wang [MSFT]

Hi Chuck,

Well, that's an interesting idea to add a new record to the data source
before binding. But I'm still not very clear about the last part of your
message: where do you get this "GridViewHelperTestObjects+TestRow"? Do you
have some complete code listing to show the issue?

On the other hand, I guess why you're adding a new record to the data
source is that you're trying to let the GridView support inserting new
record? Feel free to correct me if I'm wrong. If this is the case, actaully
we can use the footer template to insert a new row into GridView, as this
article describes:

#Adding a New Row in GridView
http://gridviewguy.com/ArticleDetails.aspx?articleID=98


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

Chuck P

Hi Walter,
I don't want to add the row to the footer and I don't care for the numerous
gridview footer add row techniques.

This DataObjectTypeName="GridViewHelperTestObjects+TestRow"
come from the ObjectDataSource's DataObjectTypeName property. What I need
to do is create a new object of this type. In the VS designer the above text
is what gets put in the property when I select this object for the
DataObjectTypeName:

public static class GridViewHelperTestObjects
{
[DataObject]
public class GridViewTestDAL
{
[DataObjectMethod(DataObjectMethodType.Select, false)]
public List<TestRow> GetAll()
{...}
....
}

public class TestRow
{

public TestRow()
{ }

}
}

When you create the ODS you have a couple or items that could be useful:

IDatasource ObjectDataSources.DataSource ()
string ObjectDataSource.TypeName

In the code in my previous post I added the new row to the list but I knew
the type ahead of time. Now I can't specify the type ahead of time, but the
name is in the ODS ObjectDataSource.TypeName. Is their some way to get the
Type from the ObjectDataSource.TypeName and then create an object. I am sure
that is what the ODS does internally for adding new rows.

http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.typename.aspx
To create an instance of the object that the ObjectDataSource control binds
to, the control uses reflection to load the type that is identified by the
type name at run time. Therefore, the value of the TypeName property can be a
partially qualified type for code that is located in the Bin or App_Code
directories or a fully qualified type name for code that is registered in the
global assembly cache. If you use the global assembly cache, you must add the
appropriate reference to the assemblies section of the Machine.config or
Web.config fil
 
C

Chuck P

Well here is what I came up with for my non-Generic method.
Let me know if their is a better way.

protected void OnObjectDataSource_Selected(object sender,
ObjectDataSourceStatusEventArgs e)
{
if (m_AddingInsertRow)//Add empty record for the first row to
the LIST
{
Type typeList = e.ReturnValue.GetType(); //List<T>
Type typeObj =
e.ReturnValue.GetType().GetGenericArguments()[0]; //<T>

object ojb = Activator.CreateInstance(typeObj); //new T

// insert the new T into the list by using InvokeMember on
the List<T>
object result = null;
object[] arguments = { 0, ojb };

result = typeList.InvokeMember("Insert",
BindingFlags.InvokeMethod, null, e.ReturnValue, arguments);

//List<T> list = (List<T>)e.ReturnValue;
//list.Insert(0, new T());
}
}
 
W

Walter Wang [MSFT]

I think your solution should be fine as long as you know before hand that
the data source is a List<T>.

On ther other hand, if you use the ObjectDataTypeName string, you can also
construct an instance of it using following code:

public void AttachDataSourceEvent()
{
IDataSource ds = GetDataSource();
ObjectDataSource ods = ds as ObjectDataSource;
if (ods != null)
{
ods.Selected += new
ObjectDataSourceStatusEventHandler(delegate(object sender,
ObjectDataSourceStatusEventArgs e) {
Type typeObj = Type.GetType(ods.DataObjectTypeName);
object ojb = Activator.CreateInstance(typeObj);

e.ReturnValue.GetType().InvokeMember("Insert",
BindingFlags.InvokeMethod, null, e.ReturnValue, new object[] { 0, ojb});
});
}
}

You still need to assume the list has a well known method to insert the
data. Not sure if you think it's better or not.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

Chuck P

Walter I seem to have trouble with this (which seems much simpler and more
direct than e.ReturnValue.GetType().GetGenericArguments()[0] ):

Type typeObj = Type.GetType(ods.DataObjectTypeName);
In my case

ods.DataObjectTypeName = GridViewHelperTestObjects+TestRow
Type.GetType(ods.DataObjectTypeName) = null

I can't get the type from the ods.DataObjectTypeName

When I do
Type typeObj = e.ReturnValue.GetType().GetGenericArguments()[0];
I get the type (Name=TestRow, FullName= GridViewHelperTestObjects+TestRow)

In the immediate window I get:
Type.GetType("TestRow")
null
Type.GetType("GridViewHelperTestObjects+TestRow")
null
 
C

Chuck P

I took your code and added
created a ObjectDataSource1_Selected
in the aspx.cs page

In the event I put:
ObjectDataSourceView odsv = sender as ObjectDataSourceView;
Type typeObj2 = Type.GetType(odsv.DataObjectTypeName);

The odsv.DataObjectTypeName is identical to what is returned in your inline
delegate ods.DataObjectTypeName.

However typeObj2 still comes back null.
 
W

Walter Wang [MSFT]

Hi Chuck,

My attached website.zip in my last reply should work as is.

As you described, so the issue became we cannot use Type.GetType() to load
the type correctly. Please try another simpler inner class and use
Type.GetType on it. My guess is that your DataObject might be in another
assembly and there's some assembly loading issue.

The difference should not be how we use the delegate or obtaining the
DataObjectTypeName from ObjectDataSource/ObjectDataSourceView. Following
code still works on my side:

public class Class1 : GridView
{
public void AttachDataSourceEvent()
{
IDataSource ds = GetDataSource();
ObjectDataSource ods = ds as ObjectDataSource;
if (ods != null)
{
//ods.Selected += new
ObjectDataSourceStatusEventHandler(delegate(object sender,
ObjectDataSourceStatusEventArgs e)
//{
// Type typeObj = Type.GetType(ods.DataObjectTypeName);
// object ojb = Activator.CreateInstance(typeObj);

// e.ReturnValue.GetType().InvokeMember("Insert",
BindingFlags.InvokeMethod, null, e.ReturnValue, new object[] { 0, ojb });
//});
ods.Selected +=new
ObjectDataSourceStatusEventHandler(ods_Selected);
}
}

void ods_Selected(object sender, ObjectDataSourceStatusEventArgs e)
{
ObjectDataSourceView dsv = (ObjectDataSourceView)sender;
Type typeObj = Type.GetType(dsv.DataObjectTypeName);
object ojb = Activator.CreateInstance(typeObj);

e.ReturnValue.GetType().InvokeMember("Insert",
BindingFlags.InvokeMethod, null, e.ReturnValue, new object[] { 0, ojb });
}
}


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

Walter Wang [MSFT]

Hi Chuck,

How's the status of this post?


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

Chuck P

I'll just leave it as:
Type typeObj =
e.ReturnValue.GetType().GetGenericArguments()[0]; //<T>

I did some searching on Type.MakeGenericType
but didn't get anywhere.
 
W

Walter Wang [MSFT]

Hi Chuck,

Since my code seems cannot reproduce the issue you mentioned, I'm wondering
if you could create a reproducible project and send it to me? Thanks.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

Walter Wang [MSFT]

Hi Chuck,

Thank you for your code. I've done some research and found the difference
between your code and mine is that the data object type is in a different
assembly other than the GridView's assembly, therefore a simple type name
string without assembly name will not load it.

The fix is to supply the assembly name when you declare ObjectDataSource:

<asp:ObjectDataSource ID="odsForGrid" runat="server"
DataObjectTypeName="GridViewHelperTestObjects+TestRow,__code"


(__code is the special assembly name for code in App_Code)



Hope this helps.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top