I have the following XAML in my Mainpage.xaml file
<StackPanel Visibility="{Binding Path=IsSignedIn, Source={x:Bind Application.Current}}">
<Button Margin="10" Click="OnSignOut">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="Account"/>
<TextBlock Text="Sign Out" Margin="5 0 0 0"/>
</StackPanel>
</Button>
</StackPanel>
I basically only want to show the sign out button, if the "state" of the application (as tracked in the IsSignedIn variable) is signed in.
Here's the code that calls the signin logic the value "IsSignedIn"
**MainPage.xaml.cs **
private async void OnSignIn(object sender, RoutedEventArgs e)
{
try
{
await(Application.Current as App).SignIn();
}
catch (Exception ex)
{
var messageDialog = new MessageDialog("Authentication Error", ex.Message);
await messageDialog.ShowAsync();
}
}
App.xaml.cs
public async Task SignIn()
{
// First, attempt silent sign in
// If the user's information is already in the app's cache,
// they won't have to sign in again.
try
{
var accounts = await PCA.GetAccountsAsync();
var silentAuthResult = await PCA
.AcquireTokenSilent(Scopes, accounts.FirstOrDefault())
.ExecuteAsync();
Console.WriteLine("User already signed in.");
}
catch (MsalUiRequiredException msalEx)
{
// This exception is thrown when an interactive sign-in is required.
Console.WriteLine("Silent token request failed, user needs to sign-in: " msalEx.Message);
// Prompt the user to sign-in
var interactiveRequest = PCA.AcquireTokenInteractive(Scopes);
var interactiveAuthResult = await interactiveRequest.ExecuteAsync();
Console.WriteLine($"Successful interactive authentication for: {interactiveAuthResult.Account.Username}");
}
catch (Exception ex)
{
Console.WriteLine("Authentication failed. See exception messsage for more details: " ex.Message);
}
await GetUserInfo();
IsSignedIn = true;
await InitializeGraphClientAsync();
}
Error Message
Invalid binding path 'Application.Current' : Property 'Application' not found on type 'MainPage'. MSGraphAPIDemo
sorry if this is a noob question - this is my first XAML / UWP attempt. Thanks.
EDIT 1
I have created a new class called MainPageViewModel.cs that looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MSGraphAPIDemo.DataProvider;
using Windows.UI.Xaml;
namespace MSGraphSPAPIDemo.Model
{
public class MainPageViewModel
{
public bool SignedIn = Application.Current.IsSignedIn;
}
}
But the error I get is:
CS1061 'Application' does not contain a definition for 'IsSignedIn' and no accessible extension method 'IsSignedIn' accepting a first argument of type 'Application' could be found (are you missing a using directive or an assembly reference?)
Inside App.xaml.cs, I have the following code:
// Is a user signed in?
private bool isSignedIn;
public bool IsSignedIn
{
get { return isSignedIn; }
set
{
isSignedIn = value;
OnPropertyChanged("IsSignedIn");
OnPropertyChanged("IsSignedOut");
}
}
CodePudding user response:
The problem here is the runtime is looking for Application.Current as a property or child of MainPage, which it is not - it's a static object.
What I would recommend is having a ViewModel that you bind to (set as your datacontext in MainWindow), then have a property inside it which reads Application.SignedIn. Like so:
public class MainPageViewModel
{
public bool SignedIn => Application.Current.IsSignedIn;
}
I also recommend checking out Microsoft.Extensions.Logging instead of using Console.WriteLine.
CodePudding user response:
I agree with @Tylor Pater that it will be better if you use a ViewModel.
I've made a simple test demo and you could check the following code which works on my side: Xaml:
<StackPanel Visibility="{Binding SignedIn}">
<Button Margin="10" Click="Button_Click">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="Account"/>
<TextBlock Text="Sign Out" Margin="5 0 0 0"/>
</StackPanel>
</Button>
</StackPanel>
MainPage:
public sealed partial class MainPage : Page
{
public MainPageViewModel ViewModel { get; set; }
public MainPage()
{
this.InitializeComponent();
ViewModel = new MainPageViewModel();
this.DataContext = ViewModel;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
public class MainPageViewModel
{
public bool SignedIn { get; set; }
public MainPageViewModel()
{
SignedIn = ((App)Application.Current).IsSignedIn;
}
}