loop througth Literials using foreach!!

I

Islam Elkhayat

In my web application i use satalite assembly to localize my web form..
Instead of set the each control text to the resourcemanager getstring()
method i try to use foreach loop

private string rmg(string key)
{
return resource.GetString("key");
}

private Literal ctrl_txt()
{
foreach (Literal lit_xyz in this.Controls)
{
string str= lit_xyz.ID;
string key= str.Substring(3);
lit_xyz.Text= rmg(key);
return lit_xyz;
}
return null;
}

this foreach genrate InvalidCastException... How can i fix this??
 
D

DalePres

foreach (Control control in Page.Controls)
{
if (control is Literal)
{
Literal lc = (Literal)control;
// Do what you want here with lc now.
}
}


HTH

DalePres
MCAD, MCDBA, MCSE
 
H

Hans Kesting

Islam said:
In my web application i use satalite assembly to localize my web form..
Instead of set the each control text to the resourcemanager getstring()
method i try to use foreach loop

private string rmg(string key)
{
return resource.GetString("key");
}

private Literal ctrl_txt()
{
foreach (Literal lit_xyz in this.Controls)
{
string str= lit_xyz.ID;
string key= str.Substring(3);
lit_xyz.Text= rmg(key);
return lit_xyz;
}
return null;
}

this foreach genrate InvalidCastException... How can i fix this??

your foreach doesn't mean "use only the Literals from
the Controls collection", it means "use every control
in Controls as if it were a Literal".
As you found out, that is not true.

The Controls collection consists of Controls that *might*
be Literals, so:

foreach (Control ctrl in this.Controls)
{
Literal lit = ctrl as Literal;
if (lit != null)
{
// work with the Literal
}
// else no literal, ignore it
}

Note: this foreach goes just one level deep, you don't find
"grandchildren" this way. If you want to find any Literal, no matter
how deep, you need to use recursion ("if this is not a Literal,
then maybe somewhere in the Controls collection of this control
there is a Literal")
 
I

Islam Elkhayat

It didn't throw Exception but also didn't work
if statment always false... so i always go to the else!!

How can i make it work??
 
D

DalePres

How are you creating your literals? In my tests of your problem, I found
that Literals created in the aspx file as <asp:LITERAL> were not available
in code even if I made sure that they were declared and instantiated in my
codebehind.

In order to get the Literals to work, I had to create them, instantiate
them, and them to Page.Controls from within my codebehind. Done that way, I
was able to access the Literal and manipulate its properties.
 
I

Islam Elkhayat

I want to loop throught literials so i don't use
Lit_1.Text= resources.GetString(key)
for each literial... if i instantiated every literial in the code behind i
will write the same long code!!!
How can i solve this issue??
 
S

Scott Allen

How are you creating your literals? In my tests of your problem, I found
that Literals created in the aspx file as <asp:LITERAL> were not available
in code even if I made sure that they were declared and instantiated in my
codebehind.

If a class is instantiated - it's available. Perhaps you meant
declared? Are you using runat="server"?
 
S

Scott Allen

If there is a literal control on the page, the control has to be
instantiated to render. Perhaps you meant you didn't want to declare a
variable for each Literal control?

In any case, I think a cleaner solution would be to create a new
control (pehaps derived from Literal or WebControl) and use the Init
event to get the string from a resource file. You could add Key as a
public property to be able to assign the key from inside the ASPX tag.

The above approach will be a cleaner, more maintainable solution.
You'll be able to use the new control on any page in your application
without cluttering eeach page with the string loading logic.

HTH,
 
D

DalePres

You're correct, if a class is instantiated it is available. But try it out.
If you create an <ASP:LITERAL runat="server" and id="Literal1" Text="My
Literal Text" /> and then, in your code behind make sure that you declare
and instantiate Literal1, they are not recognized as the same object. You
can access, modify, and do what you want with the one in your codebehind,
and it will behave as expected; the literal in your aspx file will always
render as "My Literal Text".

DalePres
 
D

DalePres

You can read my blog on strongly typed localization features built into
Visual Studio 2005 at
http://www.dalepreston.com/Blog/Archives/2005_01_29_Archive.html. While the
classes required are created automatically, in Visual Studio 2005, by the
/str switch of the ResGen.exe program, you could generate similar classes
yourself in code.

You could write a strongly typed resource class generator of your own to
read the resource xml key/value pairs. Here's an interesting article that
might help you get started: http://www.thecodeproject.com/csharp/config.asp.

Something you might try is using the VS2005 version of ResGen.exe and create
the strongly typed classes and try them in VS2003. Based on what I've seen,
I think it would work seamlessly or nearly so.

DalePres
 
P

Patrick Olurotimi Ige

Yeah i think Scott has a cleaner solution there..
I'll implement that into my recent project and see..
Patrick
 
I

Islam Elkhayat

I used Drag & drop to add the literial... So there is <ASP:Literial
runat=Server>
also in the code behind i can access any literial .Text...
but the foreach loop if condition still don't work
Do u i have to use this.Controls.Add() for each literial to access it in the
loop??
DalePres said:
You're correct, if a class is instantiated it is available. But try it
out. If you create an <ASP:LITERAL runat="server" and id="Literal1"
Text="My Literal Text" /> and then, in your code behind make sure that you
declare and instantiate Literal1, they are not recognized as the same
object. You can access, modify, and do what you want with the one in your
codebehind, and it will behave as expected; the literal in your aspx file
will always render as "My Literal Text".

DalePres
 
H

Hans Kesting

Islam said:
I used Drag & drop to add the literial... So there is <ASP:Literial
runat=Server>
also in the code behind i can access any literial .Text...
but the foreach loop if condition still don't work
Do u i have to use this.Controls.Add() for each literial to access it in the
loop??

Your "foreach" will only find direct children of the aspx/ascx, so if
your literal is (for instance) inside a <table>, it is *not* found.
You need to use recursion to find deeper literals. Something like:


private void ProcessLiterals(Control parent)
{
foreach (Control ctrl in parent.Controls)
{
Literal lit = ctrl as Literal;
if (lit != null)
{
// process the literal
}
else
{
// not a literal, look deeper
ProcessLiterals(ctrl);
}
}
}

and call it with ProcessLiterals(this);
 
I

Islam Elkhayat

I tried to create new control drived from Literial...
I add the Key property and in the render method i Can't assign the base.Text
to the ResourceManager Getstring() of my main application form....
Do i have to load my assembly & resouce manager in the new control??
 
S

Scott Allen

How do you currently load the resource manager? Can't you expose the
resource manager as a property of the form, or grab a reference from a
static helper property / method?
 
I

Islam Elkhayat

I load my resource manager in Application[lang] in Global.asax in
Begin_Request...
So how code i write my new control to comunicate with it??
I need urgenthelp plz..
 
S

Scott Allen

If you are inside of BeginRequest, then stick a reference to the
resource manager into Context.Items, i.e:

Context.Items["RM"] = resourceManager;

Later, during processing of the page and or control, you can pull out
the reference:

resourceManager = Context.Items["RM"];

The Items collection is handy this way, for more see:
http://odetocode.com/Articles/111.aspx

HTH!

--
Scott
http://www.OdeToCode.com/blogs/scott/

I load my resource manager in Application[lang] in Global.asax in
Begin_Request...
So how code i write my new control to comunicate with it??
I need urgenthelp plz..
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top