我最近向 Windows Phone Marketplace 发布了一个带有试用版的小型应用程序,但我的应用程序没有按预期工作。我在进行试用时遵循了http://code.msdn.microsoft.com/Trial-Experience-Sample-c58f21af,以便我可以调用当前的“LicenseInformation”状态并根据当前应用程序的许可证阻止或不阻止某个功能状态。根据示例应用程序,The LicenseMode property returns a value from the LicenseModes enum (Full, MissingOrRevoked, or Trial) so that your app code needs to check only a single value. There’s also a convenient Boolean IsFull property. Whenever the license mode has changed, or it is likely to have changed, TrialExperienceHelper raises its LicenseChanged event and your app code can handle that event to query LicenseMode or IsFull again. Then, your app can control the availability of features, ads, and your Buy UI as needed.
在我的应用程序中,我有一个单击事件,我想在其中执行基于当前 LicenseInformation 状态和计数的操作(计数是应用特定方面保存图像的次数)。
Settings.SavedCount.Value
记录保存按钮被点击的次数,如果计数超过100并且应用程序处于试用模式我想询问用户是否要升级,否则如果计数小于100并且应用程序处于试用模式,或者如果许可证处于完整模式,则允许用户继续保存过程(希望这是合乎逻辑的)。
void saveButton_Click(object sender, EventArgs e)
{
Settings.SavedCount.Value += 1;
if (TrialViewModel.LicenseModeString == "Trial" && Settings.SavedCount.Value > 100)
{
MessageBoxResult result = MessageBox.Show("You have saved over 100 items! Would you like to continue?", "Congratulations!", MeesageBoxButton.OKCancel);
switch (result)
{
case MessageBoxResult.OK:
//A command takes a parameter so pass null
TrialViewModel.BuyCommand.Execute(null);
break;
case MessageBoxResult.Cancel:
editPagePivotControl.SelectedIndex = 0;
break;
}
}
else if ((TrialViewModel.LicenseModeString == "Trial" && Settings.SavedCount.Value <= 100) || (TrialViewModel.LicenseModeString == "Full")
{
PerformSaveAsync();
}
}
}
在调试模式下使用 msdn 网站上的示例实现进行测试时,试用版和完整版实现正常工作,然后在发布模式下,许可证被列为 MissingOrRevoked,我认为它会在市场上被正确调用。当我在试用和完整模式下在市场上下载应用程序时,实际发生的是该PerformSaveAsync()
方法永远不会被调用(最终会保存新图像并禁用按钮)并且我可以在其他地方使用新图像。我无法弄清楚问题可能是什么?
编辑** 在研究中,我遇到了http://msdn.microsoft.com/en-us/library/aa691310(v=vs.71).aspx,它声明了The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is true.
和`•操作 x || y 对应于操作 x | y,除了仅当 x 为 false/' 时才评估 y。这会是问题的原因吗?如果是这样,它们应该如何修复?
编辑 2** 添加 TrialViewModel 和 TrialExperienceHelper.cs 以获取更多信息
试用视图模型
TrialViewModel
#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
/// <summary>
/// You can bind the Command property of a Button to BuyCommand. When the Button is clicked, BuyCommand will be
/// invoked. The Button will be enabled as long as BuyCommand can execute.
/// </summary>
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
#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