视图模型问题

ViewModel issue

我需要弹出一个 window 这需要时间。在打开新的 window 之前,按钮处于 Pressed 状态。因此,我想在单击按钮之后和 window 打开之前在 UI window 上添加一个等待指示器。 ViewModel 的代码是正确的,因为我参考了示例代码。但是为什么点了按钮没有反应呢

项目文件URL

https://supportcenter.devexpress.com/attachment/file/5268961b-ce35-4e40-b7c1-e33bffab902b

主窗口:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DevExpress.Xpf.Core;

namespace WaitIndicatorDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : DXWindow
    {

        public MainWindow()
        {
            InitializeComponent();
            vm = new MainVM();
            DataContext = vm;
        }

        MainVM vm;

        private void buttonShow_Click(object sender, RoutedEventArgs e)
        {
            vm.IsBusy = !vm.IsBusy;
        }
    }
}

查看模式:

    using DevExpress.Mvvm;

namespace WaitIndicatorDemo
{
    public class MainVM
    {
        private readonly ISplashScreenService _waitIndicatorService;

        public virtual bool IsBusy { get; set; }

        public MainVM()
        {
            _waitIndicatorService = 
                ServiceContainer.Default.GetService<ISplashScreenService>("WaitIndicatorService");
        }

        protected void OnIsBusyChanged()
        {
            if (IsBusy)
                _waitIndicatorService.ShowSplashScreen();
            else
                _waitIndicatorService.HideSplashScreen();
        }
    }
}

下面是XAML,注释的是原样例代码。复选框绑定到 IsBusy。选中复选框时会弹出指示器。我现在想在按下按钮后弹出。

    <dx:DXWindow x:Class="WaitIndicatorDemo.MainWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
             xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
             xmlns:waitIndicatorDemo="clr-namespace:WaitIndicatorDemo"
             xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
             WindowStartupLocation="CenterScreen" SnapsToDevicePixels="True"
               Title="MainWindow" Height="350" Width="525">
             <!--DataContext="{dxmvvm:ViewModelSource Type=waitIndicatorDemo:MainVM}"-->
             <!--Title="MainWindow" Height="350" Width="525">-->

    <Grid Margin="10">
        <!--<dxe:CheckEdit Content="Is Busy" IsChecked="{Binding IsBusy}" 
                       VerticalAlignment="Top" HorizontalAlignment="Left" />

        <Button Content="Button1" IsEnabled ="{Binding IsBusy, Converter={dxmvvm:BooleanNegationConverter}}"
                VerticalAlignment="Top" HorizontalAlignment="Center" Click="Button_Click"/>

        <Button Content="Button2" IsEnabled="{Binding IsBusy, Converter={dxmvvm:BooleanNegationConverter}}"
                VerticalAlignment="Top" HorizontalAlignment="Right"/>-->
        <Button x:Name="buttonShow" Content="Show"  HorizontalAlignment="Left" Height="35" Margin="50,70,0,0" VerticalAlignment="Top" Width="75" Click="buttonShow_Click" />

    </Grid>
</dx:DXWindow>

您的代码示例中有一些错误:
1- 从未调用 ViewModel 中的方法 OnIsBusyChanged
2- 您的 XAML 没有在 Window 行为中声明任何 ISplashScreenService 对象,例如 DXSplashScreenService

以下是解决这两个问题的方法。

首先,修复 ViewModel。

public class MainVM
{
    private readonly ISplashScreenService _waitIndicatorService;

    private bool _isBusy;
    public virtual bool IsBusy 
    {
        get
        {
            return _isBusy;
        }

        set
        {
            _isBusy = value;
            OnIsBusyChanged();
        }
    }

    public MainVM()
    {
        _waitIndicatorService = 
            ServiceContainer.Default.GetService<ISplashScreenService>("WaitIndicatorService");
    }

    protected void OnIsBusyChanged()
    {
        _waitIndicatorService.SetSplashScreenState("Doing some work...");

        if (IsBusy)
            _waitIndicatorService.ShowSplashScreen();
        else
            _waitIndicatorService.HideSplashScreen();
    }
}

那么,你的XAML.

<dx:DXWindow x:Class="WaitIndicatorDemo.MainWindow"
    <!-- ... -->
    Title="MainWindow" Height="350" Width="525">

    <dxmvvm:Interaction.Behaviors>
        <dx:DXSplashScreenService x:Name="WaitIndicatorService">
            <dx:DXSplashScreenService.ViewTemplate>
                <DataTemplate>
                    <Grid>
                        <Border Background="LightGray" CornerRadius="5">
                            <Border BorderBrush="#FF0072C6" BorderThickness="1" Margin="15" CornerRadius="5">
                                <Grid>
                                    <ProgressBar BorderThickness="0" Value="{Binding Progress}" Maximum="{Binding MaxProgress}" IsIndeterminate="{Binding IsIndeterminate}" Height="12" />
                                    <TextBlock Text="{Binding State, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Grid>
                            </Border>
                        </Border>
                    </Grid>
                </DataTemplate>
            </dx:DXSplashScreenService.ViewTemplate>
        </dx:DXSplashScreenService>
    </dxmvvm:Interaction.Behaviors>

    <Grid Margin="10">
        <!-- ... -->
    </Grid>
</dx:DXWindow>

这段代码主要取自How to: Use DxSplashScreenService sample