WIX UI仅显示取消按钮,但其他状态已正确配置

时间:2016-04-08 08:56:41

标签: c# wpf wix bootstrapper burn

我使用WIX bootstrapper UI编写了一个安装程序。当我运行安装程序时,只启用了取消按钮状态,但其他状态已正确配置。下面是我的模特课。

 public class BootstrapperApplicationModel
    {
        private IntPtr hwnd;
        public BootstrapperApplicationModel(
        BootstrapperApplication bootstrapperApplication)
        {
            this.BootstrapperApplication = bootstrapperApplication;
            this.hwnd = IntPtr.Zero;
        }
        public BootstrapperApplication BootstrapperApplication
        {
            get;
            private set;
        }

        public int FinalResult { get; set; }

        public void SetWindowHandle(Window view)
        {
            this.hwnd = new WindowInteropHelper(view).Handle;
        }

        public void PlanAction(LaunchAction action)
        {
            this.BootstrapperApplication.Engine.Plan(action);
        }
        public void ApplyAction()
        {
            this.BootstrapperApplication.Engine.Apply(this.hwnd);
        }
        public void LogMessage(string message)
        {
            this.BootstrapperApplication.Engine.Log(LogLevel.Standard,message);
        }
    }

以下是我的观点模型

public class InstallViewModel : BindableBase
    {
        public enum InstallState
        {
            Initializing,
            Present,
            NotPresent,
            Applying,
            Cancelled
        }
        private InstallState state;
        private string message;
        private BootstrapperApplicationModel model;
        public ICommand InstallCommand { get; private set; }
        public ICommand UninstallCommand { get; private set; }
        public ICommand CancelCommand { get; private set; }
        public string Message
        {
            get
            {
                return this.message;
            }
            set
            {
                if (this.message != value)
                {
                    this.message = value;
                    this.OnPropertyChanged(() => this.Message);
                }
            }
        }
        public InstallState State
        {
            get
            {
                return this.state;
            }
            set
            {
                if (this.state != value)
                {
                    this.state = value;
                    this.Message = this.state.ToString();
                    this.OnPropertyChanged(() => this.State);
                    this.Refresh();
                }
            }
        }
        public InstallViewModel(
        BootstrapperApplicationModel model)
        {
            this.model = model;
            this.State = InstallState.Initializing;
            this.WireUpEventHandlers();
            this.InstallCommand = new DelegateCommand(() =>
            this.model.PlanAction(LaunchAction.Install),
            () => this.State == InstallState.NotPresent);
            this.UninstallCommand = new DelegateCommand(() =>
            this.model.PlanAction(LaunchAction.Uninstall),
            () => this.State == InstallState.Present);
            this.CancelCommand = new DelegateCommand(() =>
        {
            this.model.LogMessage("Cancelling...");
            if (this.State == InstallState.Applying)
            {
                this.State = InstallState.Cancelled;
            }
            else
            {
                CustomBootstrapperApplication.Dispatcher
                .InvokeShutdown();
            }
        }, () => this.State != InstallState.Cancelled);
        }
        protected void DetectPackageComplete(
        object sender,
        DetectPackageCompleteEventArgs e)
        {
            if (e.PackageId.Equals(
        "MyInstaller.msi", StringComparison.Ordinal))
            {
                this.State = e.State == PackageState.Present ?
                    InstallState.Present : InstallState.NotPresent;
            }
        }
        protected void PlanComplete(
        object sender, PlanCompleteEventArgs e)
        {
            if (this.State == InstallState.Cancelled)
            {
                CustomBootstrapperApplication.Dispatcher
                .InvokeShutdown();
                return;
            }
            this.model.ApplyAction();
        }
        protected void ApplyBegin(
        object sender, ApplyBeginEventArgs e)
        {
            this.State = InstallState.Applying;
        }
        protected void ExecutePackageBegin(
        object sender, ExecutePackageBeginEventArgs e)
        {
            if (this.State == InstallState.Cancelled)
            {
                e.Result = Result.Cancel;
            }
        }
        protected void ExecutePackageComplete(
        object sender, ExecutePackageCompleteEventArgs e)
        {
            if (this.State == InstallState.Cancelled)
            {
                e.Result = Result.Cancel;
            }
        }
        protected void ApplyComplete(
        object sender, ApplyCompleteEventArgs e)
        {
            this.model.FinalResult = e.Status;
            CustomBootstrapperApplication.Dispatcher
            .InvokeShutdown();
        }
        private void Refresh()
        {
            CustomBootstrapperApplication.Dispatcher.Invoke(
            (Action)(() =>
            {
                ((DelegateCommand)this.InstallCommand)
                .RaiseCanExecuteChanged();
                ((DelegateCommand)this.UninstallCommand)
                .RaiseCanExecuteChanged();
                ((DelegateCommand)this.CancelCommand)
                .RaiseCanExecuteChanged();
            }));
        }
        private void WireUpEventHandlers()
        {
            this.model.BootstrapperApplication.DetectPackageComplete
            += this.DetectPackageComplete;
            this.model.BootstrapperApplication.PlanComplete += this.
        PlanComplete;
            this.model.BootstrapperApplication.ApplyComplete += this.
            ApplyComplete;
            this.model.BootstrapperApplication.ApplyBegin += this.
            ApplyBegin;
            this.model.BootstrapperApplication.ExecutePackageBegin +=
            this.ExecutePackageBegin;
            this.model.BootstrapperApplication.ExecutePackageComplete
            += this.ExecutePackageComplete;
        }
    }

以下是我对XAML及其后端代码的看法。

<Window x:Class="CustomBA.Views.InstallView"
xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc=
"http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d=
"http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
    <Window.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Margin" Value="10" />
            <Setter Property="Height" Value="30" />
        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Label Content="{Binding Message}" />
            <Button Command="{Binding InstallCommand}">
                Install</Button>
            <Button Command="{Binding UninstallCommand}">
                Uninstall</Button>
            <Button Command="{Binding CancelCommand}">
                Cancel</Button>
        </StackPanel>
    </Grid>
</Window>

public partial class InstallView : Window
    {
        public InstallView(InstallViewModel viewModel)
        {
            this.InitializeComponent();
            this.DataContext = viewModel;
            this.Closed += (sender, e) =>
            viewModel.CancelCommand.Execute(this);
        }
    }

我在这里做错了什么?请指教。

以下是我运行时的样子。

enter image description here

1 个答案:

答案 0 :(得分:1)

您似乎遇到了WPF没有重新评估命令条件的问题。 This answer很好地涵盖了您的选择 - 尝试CommandManager.InvalidateRequerySuggested();或在命令中提升CanExecuteChanged事件。