After sigin/logout, how to refresh the viewmodel of current page

Feb 27, 2012 at 8:03 AM
Edited Feb 27, 2012 at 8:11 AM

Hi, guys, I have a question about navigation in Silverlight.

Simply my app has two page Home and Data. Both guest and registered users can view all pages. The only difference is that, in Data page, Save button and Create button are disabled for guests, and only enabled for registered users.

Now, the questions is that, when a registered user logout at Data page, (I don't wanna refresh the page) how to refresh the viewmodel in order to disable the save button and create button. Because Save and Create are in Data page, navigation links are in the main page which has the frame for Data/About pages.

Should i create a property

public ViewModelBase NavigatedFrameVM { get; set; }

in MainViewModel, every time user navigate to Data, NavigatedFrameVM is set to DataViewModel, then when Logout/Login command is called, i call  NavigatedFrameVM.InitializeViewModel() ?

If there is on similar discussion, I'm going to try this idea.

In fact i don't like the idea above.  Anyone can give me a suggestion?

PS: I'm using IAuthenticationProvider service, it works very well in normal. but when Login/Logout in current page, The Role property is updated, but it seems it doesn't work. The following code is in MainViewModel:

private void OnUserRoleChanged() {
    var authenticationProvider = GetService<IAuthenticationProvider>();
    // Dirty cast, normally this would be done via clean interfaces
    ((Chuci.Authentication.AuthenticationProvider) authenticationProvider).Role = UserRole;
}

 

Thank you very much.

Coordinator
Feb 27, 2012 at 12:33 PM

What I normally do is write an AuthenticationService. In this service, you can login/logout a user. This service also has an event such as AuthenticationChanged. Then you can easily respond to change events (don't forget to use the WeakEventListener).

Mar 2, 2012 at 6:44 AM

Thank you for your reply. I tried these days, and found something making me confused.

I got the AuthenticationProvider class from the Catel examples:

 

    public class AuthenticationProvider : IAuthenticationProvider
    {
        /// <summary>
        /// Gets or sets the role the user is currently in.
        /// </summary>
        /// <value>The role.</value>
        public string Role { get; set; }

        public bool CanCommandBeExecuted(ICatelCommand command, object commandParameter)
        {
            return true;
        }

        public bool HasAccessToUIElement(FrameworkElement element, object tag, object authenticationTag)
        {
            var authenticationTagAsString = authenticationTag as string;
            if (authenticationTagAsString != null)
            {
                if (string.Compare(authenticationTagAsString, Role, System.StringComparison.OrdinalIgnoreCase) == 0)
                {
                    return true;
                }
            }

            return false;
        }
    }

 

I register the auth service in Application_Startup @ App.xaml.cs

And here is my button xaml:

 

<HyperlinkButton Margin="5,5,5,0" ToolTipService.ToolTip="Create" Command="{Binding CmdNewLoreSchema}">
   <Image Style="{StaticResource NewDocImageStyle}" />
   <!--<i:Interaction.Behaviors>
       <catel:Authentication AuthenticationTag="Engineer" Action="Disable" />
   </i:Interaction.Behaviors>-->
</HyperlinkButton>

If i uncomment the code above, Logout works well but Login doesn't work.

I browsed the Catel source code at CodePlex, but found nothing about how the AuthenticationProvider class worked. For example, in my xaml code, the Create link has both Command and Authenticationi behavior(if uncomment), will one result overwrite another ? -- In fact, when debug the result of bool OnCmdNewLoreSchemaCanExecute() is in my expect and the Role is also right one, this means both methods of AuthenticationProvider have the same result -- Ok let's ignore it.

So, I comment the behavior code and make the Command work only-- I think this will decrease some uncertainty. Now the result is ok.

I have no idea now. But the code can work in my expect.

 

 

Coordinator
Mar 2, 2012 at 9:41 AM

So, the issue is solved?

Still you get some explanation about the authentication provider. The tag that you need to set is for the Command (thus, in the constructor of the command, you can provide a tag). When the CanExecute state is determined, it uses the IAuthenticationProvider to make sure the user can actually execute the command.

The authentication provider can also be used to determine whether a user has access to a UI element (visibility). Then you need to use the Authentication behavior (which under water will also use the AuthenticationProvider).