How to set controls in a DataGrid's ItemDateBound without a costly conversion?

D

Daniel Walzenbach

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
E

Edward

maybe I didn't catch the actual meaning, in my opinion, why don't you use TemplateColumn, which contains one Label , the Visible relies on getVisible( DataBinder.Eval(Container.DataItem,"Id")).

in Datagrid, you write <asp:Lable id="some" value='getVisible(...)' />

in the page or user control , you give one method
bool getVisible( param )
return (param != myuser.id )


I want to ask one question ,how can you find the performance is blocked by the type transformation? Thanks.


I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
S

Steven Cheng[MSFT]

Hi Daniel,

As for the problem on changing the Label control's display in aps.net
datagird cell in ItemDataBound. I think the explicit cast is the only
means to retrieve the sub controls in the DataGridItem's Cells. Also, there
is another way we can do is define a helper function and call it in the
DataBinding Expression ,for example:

<asp:Label ID="lblTest" Runat="server" Visible='<%# function name %>' >
</asp:Label>

The function can be a member function of the Page class and take some
parameters which contains the sufficient info
about the current item.
Hope helps. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
D

Daniel Walzenbach

Edward, Steven,



thanks for your help. I tried you approach which worked perfectly well but
unfortunately does not improve performance significantly. Regarding Edwards'
s question: I noticed this page took long to get displayed. I therefore
commented out parts of the code I assumed being costly and found



If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <>
myUser.ID Then

CType(e.Item.Controls(2).Controls(1),
System.Web.UI.WebControls.Label).Visible = False

End If



to be the bottleneck.



Thank you!

Daniel
 
M

Martin

Looks like you would end up displaying the ID if it wasn't *your* userID - so you would display other user ID?

What happens to other fields in this row? If the whole row should be affected, a filter on the dataview might be the way to go - probably requiring a mod to your data source.

A bit more info on the wider problem may reveal a better solution.

Martin

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
D

Daniel Walzenbach

Martin,



I have a DataGrid which displays orders users have made.



Edit | OrderID | Order Description | Order ...

--------|---------------|-----------------------|--------------------

Edit | 1 | Some Order |

| 2 | Another Order |

Edit | 3 | Third Order |

Edit | 4 | Forth Order |



Since I want everybody to be able to see (in a read-only fashion) all orders I modified a DataGrid in that way that a click on the Columns "OrderID", "Order Description", "Order ..." redirects the actual user to another page where he/she can view the order details. If though the logged in user is the same user as the one who created an order I want him to be able to click on the first column "Edit" where he gets redirected to another page where he/she can edit his order. As the logged in user should see which order he can edit I want to display a label in the first column reflecting his/hers possibilities (In this example the user could edit all orders but "Another Order"). Fact is, that everything works perfectly well as it should, but the performance is not as want it to be.



Thanks for your help! I hope this description helps you better to understand what I want to do.



Daniel


Looks like you would end up displaying the ID if it wasn't *your* userID - so you would display other user ID?

What happens to other fields in this row? If the whole row should be affected, a filter on the dataview might be the way to go - probably requiring a mod to your data source.

A bit more info on the wider problem may reveal a better solution.

Martin

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
M

Martin

Hi Daniel,

I see.

I presume you have a dataset to populate the datagrid. I would try adding a field to the dataset to determine if the edit can be done, and using that as the datasource for the first column. Might not be any faster though - you'd have to try it. This solution depends on how your dataset is created - once for every user, or on a per user basis.

Also, you would probably find some performance improvement if you used a typed dataset - you wouldn't have to index your row by column name at runtime.

However like Steven says, it's probably the effort of getting the sub controls in the datagrid that is doing the damage - test this by sticking some dummy statement in place of CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False


As a minor point, in the above statement, you shouldn't have to bother doing the CType to Label, as the Control base class also has the Visible property.
From that statement it looks like you have other sub controls in that cell of the datagrid. Why do you have Controls(2).Controls(1)? Can you simplfiy that?

Interested to hear how it goes.
Martin
Martin,



I have a DataGrid which displays orders users have made.



Edit | OrderID | Order Description | Order ...

--------|---------------|-----------------------|--------------------

Edit | 1 | Some Order |

| 2 | Another Order |

Edit | 3 | Third Order |

Edit | 4 | Forth Order |



Since I want everybody to be able to see (in a read-only fashion) all orders I modified a DataGrid in that way that a click on the Columns "OrderID", "Order Description", "Order ..." redirects the actual user to another page where he/she can view the order details. If though the logged in user is the same user as the one who created an order I want him to be able to click on the first column "Edit" where he gets redirected to another page where he/she can edit his order. As the logged in user should see which order he can edit I want to display a label in the first column reflecting his/hers possibilities (In this example the user could edit all orders but "Another Order"). Fact is, that everything works perfectly well as it should, but the performance is not as want it to be.



Thanks for your help! I hope this description helps you better to understand what I want to do.



Daniel


Looks like you would end up displaying the ID if it wasn't *your* userID - so you would display other user ID?

What happens to other fields in this row? If the whole row should be affected, a filter on the dataview might be the way to go - probably requiring a mod to your data source.

A bit more info on the wider problem may reveal a better solution.

Martin

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
D

Daniel Walzenbach

Hi Martin,



Thanks for the tip using the visible property of the control instead of the label. This saves one cast :)



Regarding your question why I cast from e.Item.Controls(2).Controls(1), I pasted a part of my DataGrid (updated as you/Steve suggested).



<Columns>

<asp:ButtonColumn Visible="False" CommandName="Select"></asp:ButtonColumn>

<asp:BoundColumn Visible="False" DataField="Vorgang_OIDVorgang"></asp:BoundColumn>

<asp:TemplateColumn ItemStyle-Width="60px" ItemStyle-HorizontalAlign="Center">

<ItemTemplate>

<asp:Label CssClass="ButtonInGrid" text=" Abteilungssicht " Runat="server" ID="LabelAbteilungssicht" Visible='<%# AbteilungssichtAnzeigen(DataBinder.Eval(Container.DataItem, "Vorgang_IDKostenstelle")) %>'></asp:Label>

</ItemTemplate>

</asp:TemplateColumn>



As you can see there are two hidden columns (which explains e.Item.Controls(2)) plus a label in the third column. Therefore e.Item.Controls(2).Controls(0) is a System.Web.UI.LiteralControl and that's the reason why I have to cast e.Item.Controls(2).Controls(1) witch is the actual label.



Daniel



Hi Daniel,

I see.

I presume you have a dataset to populate the datagrid. I would try adding a field to the dataset to determine if the edit can be done, and using that as the datasource for the first column. Might not be any faster though - you'd have to try it. This solution depends on how your dataset is created - once for every user, or on a per user basis.

Also, you would probably find some performance improvement if you used a typed dataset - you wouldn't have to index your row by column name at runtime.

However like Steven says, it's probably the effort of getting the sub controls in the datagrid that is doing the damage - test this by sticking some dummy statement in place of CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False


As a minor point, in the above statement, you shouldn't have to bother doing the CType to Label, as the Control base class also has the Visible property.
From that statement it looks like you have other sub controls in that cell of the datagrid. Why do you have Controls(2).Controls(1)? Can you simplfiy that?

Interested to hear how it goes.
Martin
Martin,



I have a DataGrid which displays orders users have made.



Edit | OrderID | Order Description | Order ...

--------|---------------|-----------------------|--------------------

Edit | 1 | Some Order |

| 2 | Another Order |

Edit | 3 | Third Order |

Edit | 4 | Forth Order |



Since I want everybody to be able to see (in a read-only fashion) all orders I modified a DataGrid in that way that a click on the Columns "OrderID", "Order Description", "Order ..." redirects the actual user to another page where he/she can view the order details. If though the logged in user is the same user as the one who created an order I want him to be able to click on the first column "Edit" where he gets redirected to another page where he/she can edit his order. As the logged in user should see which order he can edit I want to display a label in the first column reflecting his/hers possibilities (In this example the user could edit all orders but "Another Order"). Fact is, that everything works perfectly well as it should, but the performance is not as want it to be.



Thanks for your help! I hope this description helps you better to understand what I want to do.



Daniel


Looks like you would end up displaying the ID if it wasn't *your* userID - so you would display other user ID?

What happens to other fields in this row? If the whole row should be affected, a filter on the dataview might be the way to go - probably requiring a mod to your data source.

A bit more info on the wider problem may reveal a better solution.

Martin

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
M

Martin

Okay,

Have you tried a typed dataset with the display/no display info in there? I don't suppose the cast saving made any time difference(?)

Martin
Hi Martin,



Thanks for the tip using the visible property of the control instead of the label. This saves one cast :)



Regarding your question why I cast from e.Item.Controls(2).Controls(1), I pasted a part of my DataGrid (updated as you/Steve suggested).



<Columns>

<asp:ButtonColumn Visible="False" CommandName="Select"></asp:ButtonColumn>

<asp:BoundColumn Visible="False" DataField="Vorgang_OIDVorgang"></asp:BoundColumn>

<asp:TemplateColumn ItemStyle-Width="60px" ItemStyle-HorizontalAlign="Center">

<ItemTemplate>

<asp:Label CssClass="ButtonInGrid" text=" Abteilungssicht " Runat="server" ID="LabelAbteilungssicht" Visible='<%# AbteilungssichtAnzeigen(DataBinder.Eval(Container.DataItem, "Vorgang_IDKostenstelle")) %>'></asp:Label>

</ItemTemplate>

</asp:TemplateColumn>



As you can see there are two hidden columns (which explains e.Item.Controls(2)) plus a label in the third column. Therefore e.Item.Controls(2).Controls(0) is a System.Web.UI.LiteralControl and that's the reason why I have to cast e.Item.Controls(2).Controls(1) witch is the actual label.



Daniel



Hi Daniel,

I see.

I presume you have a dataset to populate the datagrid. I would try adding a field to the dataset to determine if the edit can be done, and using that as the datasource for the first column. Might not be any faster though - you'd have to try it. This solution depends on how your dataset is created - once for every user, or on a per user basis.

Also, you would probably find some performance improvement if you used a typed dataset - you wouldn't have to index your row by column name at runtime.

However like Steven says, it's probably the effort of getting the sub controls in the datagrid that is doing the damage - test this by sticking some dummy statement in place of CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False


As a minor point, in the above statement, you shouldn't have to bother doing the CType to Label, as the Control base class also has the Visible property.
From that statement it looks like you have other sub controls in that cell of the datagrid. Why do you have Controls(2).Controls(1)? Can you simplfiy that?

Interested to hear how it goes.
Martin
Martin,



I have a DataGrid which displays orders users have made.



Edit | OrderID | Order Description | Order ...

--------|---------------|-----------------------|--------------------

Edit | 1 | Some Order |

| 2 | Another Order |

Edit | 3 | Third Order |

Edit | 4 | Forth Order |



Since I want everybody to be able to see (in a read-only fashion) all orders I modified a DataGrid in that way that a click on the Columns "OrderID", "Order Description", "Order ..." redirects the actual user to another page where he/she can view the order details. If though the logged in user is the same user as the one who created an order I want him to be able to click on the first column "Edit" where he gets redirected to another page where he/she can edit his order. As the logged in user should see which order he can edit I want to display a label in the first column reflecting his/hers possibilities (In this example the user could edit all orders but "Another Order"). Fact is, that everything works perfectly well as it should, but the performance is not as want it to be.



Thanks for your help! I hope this description helps you better to understand what I want to do.



Daniel


Looks like you would end up displaying the ID if it wasn't *your* userID - so you would display other user ID?

What happens to other fields in this row? If the whole row should be affected, a filter on the dataview might be the way to go - probably requiring a mod to your data source.

A bit more info on the wider problem may reveal a better solution.

Martin

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
D

Daniel Walzenbach

Indeed, one cast won't make any big difference but nevertheless.

I try to avoid using typed dataset since you are completely lost when your datastructure changes (I have not found any way to "refresh" a typed dataset when structure changes which leaves me in the position to make the changes by my own). I suppose, I am going to create the hyperlink on the server, eliminate the click event for the first visible column and place the hyperlink right in there. I assume this will work with satisfying performance :)



Thanks again for your incitation.



Daniel






Okay,

Have you tried a typed dataset with the display/no display info in there? I don't suppose the cast saving made any time difference(?)

Martin
Hi Martin,



Thanks for the tip using the visible property of the control instead of the label. This saves one cast :)



Regarding your question why I cast from e.Item.Controls(2).Controls(1), I pasted a part of my DataGrid (updated as you/Steve suggested).



<Columns>

<asp:ButtonColumn Visible="False" CommandName="Select"></asp:ButtonColumn>

<asp:BoundColumn Visible="False" DataField="Vorgang_OIDVorgang"></asp:BoundColumn>

<asp:TemplateColumn ItemStyle-Width="60px" ItemStyle-HorizontalAlign="Center">

<ItemTemplate>

<asp:Label CssClass="ButtonInGrid" text=" Abteilungssicht " Runat="server" ID="LabelAbteilungssicht" Visible='<%# AbteilungssichtAnzeigen(DataBinder.Eval(Container.DataItem, "Vorgang_IDKostenstelle")) %>'></asp:Label>

</ItemTemplate>

</asp:TemplateColumn>



As you can see there are two hidden columns (which explains e.Item.Controls(2)) plus a label in the third column. Therefore e.Item.Controls(2).Controls(0) is a System.Web.UI.LiteralControl and that's the reason why I have to cast e.Item.Controls(2).Controls(1) witch is the actual label.



Daniel



Hi Daniel,

I see.

I presume you have a dataset to populate the datagrid. I would try adding a field to the dataset to determine if the edit can be done, and using that as the datasource for the first column. Might not be any faster though - you'd have to try it. This solution depends on how your dataset is created - once for every user, or on a per user basis.

Also, you would probably find some performance improvement if you used a typed dataset - you wouldn't have to index your row by column name at runtime.

However like Steven says, it's probably the effort of getting the sub controls in the datagrid that is doing the damage - test this by sticking some dummy statement in place of CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False


As a minor point, in the above statement, you shouldn't have to bother doing the CType to Label, as the Control base class also has the Visible property.
From that statement it looks like you have other sub controls in that cell of the datagrid. Why do you have Controls(2).Controls(1)? Can you simplfiy that?

Interested to hear how it goes.
Martin
Martin,



I have a DataGrid which displays orders users have made.



Edit | OrderID | Order Description | Order ...

--------|---------------|-----------------------|--------------------

Edit | 1 | Some Order |

| 2 | Another Order |

Edit | 3 | Third Order |

Edit | 4 | Forth Order |



Since I want everybody to be able to see (in a read-only fashion) all orders I modified a DataGrid in that way that a click on the Columns "OrderID", "Order Description", "Order ..." redirects the actual user to another page where he/she can view the order details. If though the logged in user is the same user as the one who created an order I want him to be able to click on the first column "Edit" where he gets redirected to another page where he/she can edit his order. As the logged in user should see which order he can edit I want to display a label in the first column reflecting his/hers possibilities (In this example the user could edit all orders but "Another Order"). Fact is, that everything works perfectly well as it should, but the performance is not as want it to be.



Thanks for your help! I hope this description helps you better to understand what I want to do.



Daniel


Looks like you would end up displaying the ID if it wasn't *your* userID - so you would display other user ID?

What happens to other fields in this row? If the whole row should be affected, a filter on the dataview might be the way to go - probably requiring a mod to your data source.

A bit more info on the wider problem may reveal a better solution.

Martin

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
M

Martin

It should refresh in the normal build process, but I can't swear to it.

Two alternatives are:
*Rebuild* project/solution
or
right click xsd file in solution explorer, click "Run Custom Tool"

Martin

Indeed, one cast won't make any big difference but nevertheless.

I try to avoid using typed dataset since you are completely lost when your datastructure changes (I have not found any way to "refresh" a typed dataset when structure changes which leaves me in the position to make the changes by my own). I suppose, I am going to create the hyperlink on the server, eliminate the click event for the first visible column and place the hyperlink right in there. I assume this will work with satisfying performance :)



Thanks again for your incitation.



Daniel






Okay,

Have you tried a typed dataset with the display/no display info in there? I don't suppose the cast saving made any time difference(?)

Martin
Hi Martin,



Thanks for the tip using the visible property of the control instead of the label. This saves one cast :)



Regarding your question why I cast from e.Item.Controls(2).Controls(1), I pasted a part of my DataGrid (updated as you/Steve suggested).



<Columns>

<asp:ButtonColumn Visible="False" CommandName="Select"></asp:ButtonColumn>

<asp:BoundColumn Visible="False" DataField="Vorgang_OIDVorgang"></asp:BoundColumn>

<asp:TemplateColumn ItemStyle-Width="60px" ItemStyle-HorizontalAlign="Center">

<ItemTemplate>

<asp:Label CssClass="ButtonInGrid" text=" Abteilungssicht " Runat="server" ID="LabelAbteilungssicht" Visible='<%# AbteilungssichtAnzeigen(DataBinder.Eval(Container.DataItem, "Vorgang_IDKostenstelle")) %>'></asp:Label>

</ItemTemplate>

</asp:TemplateColumn>



As you can see there are two hidden columns (which explains e.Item.Controls(2)) plus a label in the third column. Therefore e.Item.Controls(2).Controls(0) is a System.Web.UI.LiteralControl and that's the reason why I have to cast e.Item.Controls(2).Controls(1) witch is the actual label.



Daniel



Hi Daniel,

I see.

I presume you have a dataset to populate the datagrid. I would try adding a field to the dataset to determine if the edit can be done, and using that as the datasource for the first column. Might not be any faster though - you'd have to try it. This solution depends on how your dataset is created - once for every user, or on a per user basis.

Also, you would probably find some performance improvement if you used a typed dataset - you wouldn't have to index your row by column name at runtime.

However like Steven says, it's probably the effort of getting the sub controls in the datagrid that is doing the damage - test this by sticking some dummy statement in place of CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False


As a minor point, in the above statement, you shouldn't have to bother doing the CType to Label, as the Control base class also has the Visible property.
From that statement it looks like you have other sub controls in that cell of the datagrid. Why do you have Controls(2).Controls(1)? Can you simplfiy that?

Interested to hear how it goes.
Martin
Martin,



I have a DataGrid which displays orders users have made.



Edit | OrderID | Order Description | Order ...

--------|---------------|-----------------------|--------------------

Edit | 1 | Some Order |

| 2 | Another Order |

Edit | 3 | Third Order |

Edit | 4 | Forth Order |



Since I want everybody to be able to see (in a read-only fashion) all orders I modified a DataGrid in that way that a click on the Columns "OrderID", "Order Description", "Order ..." redirects the actual user to another page where he/she can view the order details. If though the logged in user is the same user as the one who created an order I want him to be able to click on the first column "Edit" where he gets redirected to another page where he/she can edit his order. As the logged in user should see which order he can edit I want to display a label in the first column reflecting his/hers possibilities (In this example the user could edit all orders but "Another Order"). Fact is, that everything works perfectly well as it should, but the performance is not as want it to be.



Thanks for your help! I hope this description helps you better to understand what I want to do.



Daniel


Looks like you would end up displaying the ID if it wasn't *your* userID - so you would display other user ID?

What happens to other fields in this row? If the whole row should be affected, a filter on the dataview might be the way to go - probably requiring a mod to your data source.

A bit more info on the wider problem may reveal a better solution.

Martin

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
D

Daniel Walzenbach

Thank you Martin,

I will give it a try.

Daniel

It should refresh in the normal build process, but I can't swear to it.

Two alternatives are:
*Rebuild* project/solution
or
right click xsd file in solution explorer, click "Run Custom Tool"

Martin

Indeed, one cast won't make any big difference but nevertheless.

I try to avoid using typed dataset since you are completely lost when your datastructure changes (I have not found any way to "refresh" a typed dataset when structure changes which leaves me in the position to make the changes by my own). I suppose, I am going to create the hyperlink on the server, eliminate the click event for the first visible column and place the hyperlink right in there. I assume this will work with satisfying performance :)



Thanks again for your incitation.



Daniel






Okay,

Have you tried a typed dataset with the display/no display info in there? I don't suppose the cast saving made any time difference(?)

Martin
Hi Martin,



Thanks for the tip using the visible property of the control instead of the label. This saves one cast :)



Regarding your question why I cast from e.Item.Controls(2).Controls(1), I pasted a part of my DataGrid (updated as you/Steve suggested).



<Columns>

<asp:ButtonColumn Visible="False" CommandName="Select"></asp:ButtonColumn>

<asp:BoundColumn Visible="False" DataField="Vorgang_OIDVorgang"></asp:BoundColumn>

<asp:TemplateColumn ItemStyle-Width="60px" ItemStyle-HorizontalAlign="Center">

<ItemTemplate>

<asp:Label CssClass="ButtonInGrid" text=" Abteilungssicht " Runat="server" ID="LabelAbteilungssicht" Visible='<%# AbteilungssichtAnzeigen(DataBinder.Eval(Container.DataItem, "Vorgang_IDKostenstelle")) %>'></asp:Label>

</ItemTemplate>

</asp:TemplateColumn>



As you can see there are two hidden columns (which explains e.Item.Controls(2)) plus a label in the third column. Therefore e.Item.Controls(2).Controls(0) is a System.Web.UI.LiteralControl and that's the reason why I have to cast e.Item.Controls(2).Controls(1) witch is the actual label.



Daniel



Hi Daniel,

I see.

I presume you have a dataset to populate the datagrid. I would try adding a field to the dataset to determine if the edit can be done, and using that as the datasource for the first column. Might not be any faster though - you'd have to try it. This solution depends on how your dataset is created - once for every user, or on a per user basis.

Also, you would probably find some performance improvement if you used a typed dataset - you wouldn't have to index your row by column name at runtime.

However like Steven says, it's probably the effort of getting the sub controls in the datagrid that is doing the damage - test this by sticking some dummy statement in place of CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False


As a minor point, in the above statement, you shouldn't have to bother doing the CType to Label, as the Control base class also has the Visible property.
From that statement it looks like you have other sub controls in that cell of the datagrid. Why do you have Controls(2).Controls(1)? Can you simplfiy that?

Interested to hear how it goes.
Martin
Martin,



I have a DataGrid which displays orders users have made.



Edit | OrderID | Order Description | Order ...

--------|---------------|-----------------------|--------------------

Edit | 1 | Some Order |

| 2 | Another Order |

Edit | 3 | Third Order |

Edit | 4 | Forth Order |



Since I want everybody to be able to see (in a read-only fashion) all orders I modified a DataGrid in that way that a click on the Columns "OrderID", "Order Description", "Order ..." redirects the actual user to another page where he/she can view the order details. If though the logged in user is the same user as the one who created an order I want him to be able to click on the first column "Edit" where he gets redirected to another page where he/she can edit his order. As the logged in user should see which order he can edit I want to display a label in the first column reflecting his/hers possibilities (In this example the user could edit all orders but "Another Order"). Fact is, that everything works perfectly well as it should, but the performance is not as want it to be.



Thanks for your help! I hope this description helps you better to understand what I want to do.



Daniel


Looks like you would end up displaying the ID if it wasn't *your* userID - so you would display other user ID?

What happens to other fields in this row? If the whole row should be affected, a filter on the dataview might be the way to go - probably requiring a mod to your data source.

A bit more info on the wider problem may reveal a better solution.

Martin

Hi,



I want to display a Label in a DataGrid according to some condition. I therefore check whether the condition is true in the ItemDateBound EventHandler of the DataGrid. Unfortunately the conversion is extremely costly in performance. Does anybody know how I could set the label (of the whole content of the TableCell) to .Visible = False without converting e.Item.Controls(2) to a System.Web.UI.WebControls.Label?





Private Sub DataGrid_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid.ItemDataBound



If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then

Dim button As LinkButton = CType(e.Item.Cells(0).Controls(0), LinkButton)

Dim col As Integer

For col = 0 To e.Item.Cells.Count - 1

e.Item.Cells(col).Attributes("onClick") = Page.GetPostBackClientHyperlink(button, col.ToString)

Next



' This conversion is EXTREMELY costly.

If CInt(CType(e.Item.DataItem, System.data.DataRowView).Item("ID")) <> myUser.ID Then

CType(e.Item.Controls(2).Controls(1), System.Web.UI.WebControls.Label).Visible = False

End If



End If



End Sub



Thanks a lot in advance!



Daniel
 
Y

Yan-Hong Huang[MSFT]

Hello Diniel,

I was reviewing the thread. It seems that the question is OK now. If you have any more concerns on this issue, please feel free to post here and
we will follow up.

Thanks very much.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
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

Top