Public delegate & event not seen in parent instantiation

G

Guest

I have a partial class of a UserControl coded as follows:

public partial class Login : System.Windows.Controls.UserControl
{
public delegate void StartingLoginHandler(string message);
public event StartingLoginHandler StartingLogin;

public Login()
{
InitializeComponent();
}

protected void OnStartingLogin(string message)
{
if (StartingLogin != null)
{
StartingLogin(message);
}
}
}

When I instantiate a UserControl Login() object in the parent page.xaml.cs I
cannot see the event to attach to it. It won't give any Intellisense on the
event and if I just go ahead and type it in like:

oLogin.StartingLogin += oLogin.StartingLoginHandler(delegate_method);

it won't compile; compiler just reports StartingLogin doesn't exist.

What is the solution or a work-around please?
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

When I instantiate a UserControl Login() object in the parent page.xaml.cs
I
cannot see the event to attach to it. It won't give any Intellisense on
the
event and if I just go ahead and type it in like:

oLogin.StartingLogin += oLogin.StartingLoginHandler(delegate_method);

it won't compile; compiler just reports StartingLogin doesn't exist.

What is the solution or a work-around please?

Of course it cannot be seen, as it's not defined in UserControl.

This is what you should do:

Login l = yourControl as Login;
if ( l != null )
l.StartingLogin += oLogin.StartingLoginHandler(delegate_method);
else
throw new Exception( "Incorrect control type");
 
G

Guest

l.StartingLogin now shows in Intellisense. However, both the following two
lines throw compiler errors:

l.StartingLogin +=
oLogin.StartingLoginHandler(delegate_method);
l.StartingLogin += l.StartingLoginHandler(delegate_method);

'System.Windows.Controls.UserControl' does not contain a definition for
'StartingLoginHandler'

Do you have any suggestions for a work-around, please?
 
B

Ben Voigt

Mike McAllister said:
l.StartingLogin now shows in Intellisense. However, both the following two
lines throw compiler errors:

l.StartingLogin +=
oLogin.StartingLoginHandler(delegate_method);
l.StartingLogin += l.StartingLoginHandler(delegate_method);

'System.Windows.Controls.UserControl' does not contain a definition for
'StartingLoginHandler'

Do you have any suggestions for a work-around, please?

Change the type of the variable from UserControl to the exact derived type,
to be able to use your additional methods/events/properties.
 
G

Guest

Here is a solution that works I found by trial and error:

oLogin = new Login(ref oAgilityService1, ref
dsSessionCustomersAndPV);
//Workaround from Microsoft Managed Newsgroups...
Login l = oLogin as Login;
if (l != null)
{
l.StartingLogin += new Login.StartingLoginHandler(StartLogin);
l.EndingLogin += new Login.EndingLoginHandler(EndLogin);
l.LoginMessage += new Login.LoginMessageHandler(LoginMessage);
}
else
{
throw new Exception("Incorrect control type");
}
 
J

Jon Skeet [C# MVP]

Mike McAllister said:
Here is a solution that works I found by trial and error:

oLogin = new Login(ref oAgilityService1, ref
dsSessionCustomersAndPV);
//Workaround from Microsoft Managed Newsgroups...
Login l = oLogin as Login;
if (l != null)
{
l.StartingLogin += new Login.StartingLoginHandler(StartLogin);
l.EndingLogin += new Login.EndingLoginHandler(EndLogin);
l.LoginMessage += new Login.LoginMessageHandler(LoginMessage);
}
else
{
throw new Exception("Incorrect control type");
}

One style hint - if you're going to throw an exception if something
isn't the right type, just cast it. That will give a more specific
exception, and avoid cluttering up your code. The above becomes just:

oLogin = new Login(ref oAgilityService1,
ref dsSessionCustomersAndPV);

//Workaround from Microsoft Managed Newsgroups...
Login l = (Login) oLogin;
l.StartingLogin += new Login.StartingLoginHandler(StartLogin);
l.EndingLogin += new Login.EndingLoginHandler(EndLogin);
l.LoginMessage += new Login.LoginMessageHandler(LoginMessage);

Of course, in this case there's no risk anyway, because oLogin is
clearly a Login given the call to the constructor.

Are you sure you really need to pass those Login parameters by
reference, by the way?
 
G

Guest

Great suggestion on the casting! Thanks.

I think I need to pass them by ref; but I'm always learning...

Here's my scenario:

Login is short-lived. It's a XAML UserControl that logs into a web service
SOA. The DataSet by ref stores all the application state information from the
login.

I'm passing the web service by ref because it will be used for many other
calls elsewhere in the applicationI'm just starting.

I know this is a bit off-topic, but the application I'm just now starting
will eventually be 1,300+ screens and will be an .xbap application of a full
ERP system.

What we're designing is a type of MDI where UserControls will be
instantiated at runtime. A Manager for those UserControls will live at the
root level for the duration of the application.

I very much appreciate your comments and suggestions as I want to make sure
I have and excellent ground-level architecture for this 'very large' project.

Any suggestions are welcome.
 
J

Jon Skeet [C# MVP]

Mike McAllister said:
Great suggestion on the casting! Thanks.

I think I need to pass them by ref; but I'm always learning...

Here's my scenario:

Login is short-lived. It's a XAML UserControl that logs into a web service
SOA. The DataSet by ref stores all the application state information from the
login.

I'm passing the web service by ref because it will be used for many other
calls elsewhere in the applicationI'm just starting.

I suspect you don't really understand what passing by reference means
then.

See http://pobox.com/~skeet/csharp/parameters.html for a fairly
thorough description.
I know this is a bit off-topic, but the application I'm just now starting
will eventually be 1,300+ screens and will be an .xbap application of a full
ERP system.

In that case it's definitely worth making sure you understand pass by
reference vs pass by value (and value types vs reference types) before
making all of those screens :)
 
L

Linda Liu [MSFT]

Hi Mike,

There're two kinds of types in .NET world, i.e. value type and reference
type.

A value-type variable contains its data directly as opposed to a
reference-type variable, which contains a reference to its data. Therefore,
passing a value-type variable to a method means passing a copy of the
variable to the method. Any changes to the parameter that take place inside
the method have no effect on the original data stored in the variable.

If you want the called method to change the value of the parameter, you
have to pass it by reference, using the ref or out keyword.

A variable of a reference type does not contain its data directly; it
contains a reference to its data. When you pass a reference-type parameter
by value, it is possible to change the data pointed to by the reference,
such as the value of a class member. However, you cannot change the value
of the reference itself; that is, you cannot use the same reference to
allocate memory for a new class and have it persist outside the block. To
do that, pass the parameter using the ref or out keyword.

In your practice, both the DataSet and WebService types are of reference
type. If you don't intend to change the values of the reference themselves,
you needn't use the ref keyword.

In addition, you may place the DataSet and WebService objects at the root
level for the duration of the application, to enable them to be used for
many other calls in the application.

Hope this helps.
If you have anything unclear, please feel free to let me know.


Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

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

Guest

Linda, Thank you.

Your very excellent description matches my understanding and coding
practices. Thanks for taking the time to make sure I understand. You have
gone 'above and beyond' which I appreciate very much.

Thanks,
 

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