我试图访问我创建的称为TrialViewModel的 View 模型中的属性,该属性将帮助我进行试用应用程序的实现。 TrialViewModel链接到一个名为TrialExperienceHelper.cs的类,其中包含用于购买应用程序,获取试用许可证模式等的方法。当我尝试从我的 View 访问TrialViewModel时,我收到了NullReferenceException,但不确定为什么?

TrialViewModel

public class TrialViewModel : PropertyChangedNotifier
{
    #region fields
    private RelayCommand buyCommand;
    #endregion fields

    #region constructors
    public TrialViewModel()
    {
        // Subscribe to the helper class's static LicenseChanged event so that we can re-query its LicenseMode property when it changes.
        TrialExperienceHelper.LicenseChanged += TrialExperienceHelper_LicenseChanged;
    }
    #endregion constructors

    #region properties
    public RelayCommand BuyCommand
    {
        get
        {
            if (this.buyCommand == null)
            {
                // The RelayCommand is constructed with two parameters - the action to perform on invocation,
                // and the condition under which the command can execute. It's important to call RaiseCanExecuteChanged
                // on a command whenever its can-execute condition might have changed. Here, we do that in the TrialExperienceHelper_LicenseChanged
                // event handler.
                this.buyCommand = new RelayCommand(
                    param => TrialExperienceHelper.Buy(),
                    param => TrialExperienceHelper.LicenseMode == TrialExperienceHelper.LicenseModes.Trial);
            }
            return this.buyCommand;
        }
    }

    public string LicenseModeString
    {
        get
        {
            return TrialExperienceHelper.LicenseMode.ToString()/* + ' ' + AppResources.ModeString*/;
        }
    }
    #endregion properties

    #region event handlers
    // Handle TrialExperienceHelper's LicenseChanged event by raising property changed notifications on the
    // properties and commands that
    internal void TrialExperienceHelper_LicenseChanged()
    {
        this.RaisePropertyChanged("LicenseModeString");
        this.BuyCommand.RaiseCanExecuteChanged();
    }
    #endregion event handlers
}

TrialExperienceHelper.cs
public static class TrialExperienceHelper
{
    #region enums
    /// <summary>
    /// The LicenseModes enumeration describes the mode of a license.
    /// </summary>
    public enum LicenseModes
    {
        Full,
        MissingOrRevoked,
        Trial
    }
    #endregion enums

    #region fields
#if DEBUG
    // Determines how a debug build behaves on launch. This field is set to LicenseModes.Full after simulating a purchase.
    // Calling the Buy method (or navigating away from the app and back) will simulate a purchase.
    internal static LicenseModes simulatedLicMode = LicenseModes.Trial;
#endif // DEBUG
    private static bool isActiveCache;
    private static bool isTrialCache;
    #endregion fields

    #region constructors
    // The static constructor effectively initializes the cache of the state of the license when the app is launched. It also attaches
    // a handler so that we can refresh the cache whenever the license has (potentially) changed.
    static TrialExperienceHelper()
    {
        TrialExperienceHelper.RefreshCache();
        PhoneApplicationService.Current.Activated += (object sender, ActivatedEventArgs e) => TrialExperienceHelper.
#if DEBUG
            // In debug configuration, when the user returns to the application we will simulate a purchase.
OnSimulatedPurchase();
#else // DEBUG
            // In release configuration, when the user returns to the application we will refresh the cache.
RefreshCache();
#endif // DEBUG
    }
    #endregion constructors

    #region properties
    /// <summary>
    /// The LicenseMode property combines the active and trial states of the license into a single
    /// enumerated value. In debug configuration, the simulated value is returned. In release configuration,
    /// if the license is active then it is either trial or full. If the license is not active then
    /// it is either missing or revoked.
    /// </summary>
    public static LicenseModes LicenseMode
    {
        get
        {
#if DEBUG
            return simulatedLicMode;
#else // DEBUG
            if (TrialExperienceHelper.isActiveCache)
            {
                return TrialExperienceHelper.isTrialCache ? LicenseModes.Trial : LicenseModes.Full;
            }
            else // License is inactive.
            {
                return LicenseModes.MissingOrRevoked;
            }
#endif // DEBUG
        }
    }

    /// <summary>
    /// The IsFull property provides a convenient way of checking whether the license is full or not.
    /// </summary>
    public static bool IsFull
    {
        get
        {
            return (TrialExperienceHelper.LicenseMode == LicenseModes.Full);
        }
    }
    #endregion properties

    #region methods
    /// <summary>
    /// The Buy method can be called when the license state is trial. the user is given the opportunity
    /// to buy the app after which, in all configurations, the Activated event is raised, which we handle.
    /// </summary>
    public static void Buy()
    {
        MarketplaceDetailTask marketplaceDetailTask = new MarketplaceDetailTask();
        marketplaceDetailTask.ContentType = MarketplaceContentType.Applications;
        marketplaceDetailTask.Show();
    }

    /// <summary>
    /// This method can be called at any time to refresh the values stored in the cache. We re-query the application object
    /// for the current state of the license and cache the fresh values. We also raise the LicenseChanged event.
    /// </summary>
    public static void RefreshCache()
    {
        TrialExperienceHelper.isActiveCache = CurrentApp.LicenseInformation.IsActive;
        TrialExperienceHelper.isTrialCache = CurrentApp.LicenseInformation.IsTrial;
        TrialExperienceHelper.RaiseLicenseChanged();
    }

    private static void RaiseLicenseChanged()
    {
        if (TrialExperienceHelper.LicenseChanged != null)
        {
            TrialExperienceHelper.LicenseChanged();
        }
    }

#if DEBUG
    private static void OnSimulatedPurchase()
    {
        TrialExperienceHelper.simulatedLicMode = LicenseModes.Full;
        TrialExperienceHelper.RaiseLicenseChanged();
    }
#endif // DEBUG
    #endregion methods

    #region events
    /// <summary>
    /// The static LicenseChanged event is raised whenever the value of the LicenseMode property has (potentially) changed.
    /// </summary>
    public static event LicenseChangedEventHandler LicenseChanged;
    #endregion events
}

看法
protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        modeTextBlock.Text = TrialViewModel.LicenseModeString;  //NullReferenceException
    }

 private void popupButton_Click(object sender, RoutedEventArgs e)
    {
        var button = sender as Button;
        string option = button.Name;

        switch (option)
        {
            case "purchaseButton":
                // A command takes a parameter and in this case we can pass null.
                TrialViewModel.BuyCommand.Execute(null); //NullReferenceException
                break;
            case "cancelButton":
                if (editPagePivotControl != null && editPagePivotControl.SelectedIndex != 0)
                {
                    editPagePivotControl.SelectedIndex = 0;
                }
                break;
        }
    }

    private TrialViewModel TrialViewModel
    {
        get
        {
            return this.DataContext as TrialViewModel;
        }
    }

有任何想法吗?我确实需要能够访问Buy命令以将用户发送到Marketplace购买页面,以及获得当前的许可证模式。

最佳答案

设置数据上下文

this.DataContext = new TrialViewModel();

关于c# - ViewModel在页面上为Null,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19336719/

10-12 23:56