Click here to Skip to main content
15,892,537 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,

I have a small problem...
Scenario:

1. I have a navigation application in Silverlight (SL)
2. I have a usercontrol with the menu (just simple buttons) called MainMenu on the mainpage.
3. When I click on the button (in the menu) "Login", the SL app navigates to that page by a navigationpanel.
4. When I login the menu has to change (button Login should become Logout for example).

At this point I have no clue how I can let the usercontrol MainMenu know the button needs to change.

I tried to look, but I have no idea where to look and on what keywords.

So very basic: How can I call a function in a usercontrol on the mainpage from a page?

Can anybody help?

Thanks!
Posted

Instead of trying to find or keep track of controls (which may change in future versions of your code) and modifying them with code at runtime, I would go with a more data-centric method - WPF/Silverlight are made for this.

Generate a business application sample from the visual studio project templates...check out the LoginStatus.xaml/LoginStatus.xaml.cs files to see another way of doing this with bindings and visual states.
Basically, there's a singleton/static object that represents the logged-in/logged-out state. This class has events for loggedin and loggedout. Any element (like a usercontrol) you have that needs to know when the state changes can subscribe to these events and in the event handlers set its state appropriately (like changing a "log in" button to "log out"). This puts the code right in the usercontrol's class instead of having to track or find usercontrols from other pages/controls.

For example, if you wrapped your authentication code in a singleton class like this
public class AuthenticationService : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Implementation

    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

    #endregion

    private static volatile AuthenticationService instance;
    private static object syncRoot = new Object();

    private AuthenticationService()
    {
    }

    public static AuthenticationService Current
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new AuthenticationService();
                }
            }

            return instance;
        }
    }

    public event EventHandler<EventArgs> LoggedIn;
    public event EventHandler<EventArgs> LoggedOut;

    public void LogIn()
    {
        //if and when loginsuccessful
        //{

        IsLoggedIn = true;

        EventHandler<EventArgs> evnt = LoggedIn;
            if (evnt != null)
            {
                evnt(this, new EventArgs());
            }
        //}
    }

    public void LogOut()
    {
        //if and when logoutsuccessful
        //{

        IsLoggedIn = false;

        EventHandler<EventArgs> evnt = LoggedOut;
        if (evnt != null)
        {
            evnt(this, new EventArgs());
        }
        //}
    }

    bool _isLoggedIn = false;
    public bool IsLoggedIn
    {
        get { return _isLoggedIn; }
        set
        {
            if (_isLoggedIn != value)
            {
                _isLoggedIn = value;
                OnPropertyChanged("IsLoggedIn");
            }
        }
    }
}


...then a usercontrol that needs to update itself based on the loggedin/loggedout status can simply do something like this
public MyUserControl()
{
    InitializeComponent();

    // Subscribe to loggedin/loggedout events so we can update our UI
    AuthenticationService authentication = AuthenticationService.Current;
    authentication.LoggedIn += new EventHandler<EventArgs>(authentication_LoggedIn);
    authentication.LoggedOut += new EventHandler<EventArgs>(authentication_LoggedOut);
}

void authentication_LoggedIn(object sender, EventArgs e)
{
    // Change button text to "Log Out"
}

void authentication_LoggedOut(object sender, EventArgs e)
{
    // Change button text to "Log In"
}


No need for another page to know about MyUserControl :)
 
Share this answer
 
v6
Comments
Ken Elz 16-Jul-11 4:20am    
Thanks for the code. I will look at it. In the meanwhile... I had a "bright light"... I'm also using a class. I declared a variable on static level. When the usercontrol (menu) is made that variable is filled with the usercontrol. That way all other pages and usercontrols can access the menu. Problem solved.
Humm, alot of code... Can't really find my way in the application to the answer I need... A little hint please? Perhaps some code I need? Please know I don't need this functionality for login/-out only. In other parts of the app are similar functions/needs.

Thanks
 
Share this answer
 
v2
Comments
Mark Salsbery 15-Jul-11 14:13pm    
Please don't post questions/replies as solutions. There's comment and reply links here for that :)

I gave you a big hint....track the loggedin/loggedout state in a single object. Any place you need to set something based on this state you just bind to or subscribe to events on that single object. Then none of your control classes need to have intimate knowledge of any other class (for example, main page doesn't need to know of the existence of some usercontrol with a button in it whose text needs to be changed).
Ken Elz 15-Jul-11 14:25pm    
Sorry, don't know why I did not use the comment.

I will look into it.

Thanks
Mark Salsbery 15-Jul-11 14:27pm    
Added code sample to solution above...hope it helps!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900