TaskbarItemInfo не показывает неопределенное состояние прогресса

#wpf #xaml #progress-bar #taskbar

#wpf #xaml #индикатор выполнения #панель задач

Вопрос:

Я привел простой пример моей проблемы. Существует окно, имеющее привязку DataContext к классу MainWindowViewModel. Окно содержит сетку с кнопкой и индикатором прогресса. Команда кнопки подключается к RelayCommand ViewModel, которая сначала выполняет приращение целочисленного свойства «Процент» от 0 до 100. Панель прогресса показывает прогресс просто отлично! Окно содержит свойство TaskbarItemInfo, и последнее имеет два свойства: значение progress для двойного свойства «Count» и значение ProgressState для свойства TaskbarItemProgressState «State», все свойства в в MainWindowViewModel. TaskbarItemInfo также отлично показывает приращение от 0 до 1.

Но во второй части начального метода прогресс становится неопределенным в течение 5 секунд. Хотя это отлично отображается на панели выполнения, на панели задач этого нет. Я использовал как преобразователь из логического значения в TaskbarItemProgressState в путь свойства ProgressState (IsIndeterminate ), так и привязку к отдельному состоянию свойства, как показано в приведенном ниже коде.

MainWindow.xaml

 <Window x:Class="ProgressState.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ProgressState"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="400">
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>

    <Window.Resources>
        <local:BoolToProgressStateConverter x:Key="boolToProgressStateConverter"/>
    </Window.Resources>
    
    <Window.TaskbarItemInfo>
        <TaskbarItemInfo ProgressValue="{Binding Count, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
                         ProgressState="{Binding State, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
        <!--ProgressState="{Binding IsIndeterminate, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource boolToProgressStateConverter}}"-->
    </Window.TaskbarItemInfo>
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Content="Start progress" Grid.Row="0" Height="30" Width="100"
                Command="{Binding Start}" IsEnabled="{Binding IsEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
        <ProgressBar Grid.Row="1" Height="20" Margin="10 0"
                     Value="{Binding Percent, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
                     IsIndeterminate="{Binding IsIndeterminate, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
    </Grid>
</Window>
  

MainWindowViewModel.cs

 using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Shell;

namespace ProgressState
{
    public class MainWindowViewModel : ViewModelBase
    {
        private double count;
        private bool isIndeterminate;
        private int percent;
        private bool isEnabled = true;
        private TaskbarItemProgressState state;

        public RelayCommand Start { get; set; }

        public MainWindowViewModel()
        {
            Start = new RelayCommand(OnStart, CanStart);
        }

        public TaskbarItemProgressState State
        {
            get
            {
                if (IsIndeterminate)
                {
                    state = TaskbarItemProgressState.Indeterminate;
                }
                else
                {
                    state = TaskbarItemProgressState.Normal;
                }
                return state; 
            }
        }

        public bool IsEnabled
        {
            get
            {
                return isEnabled; 
            }
            set 
            {
                if (value != isEnabled)
                {
                    isEnabled = value;
                    RaisePropertyChanged(nameof(IsEnabled));
                }
            }
        }


        public bool IsIndeterminate
        {
            get 
            {
                return isIndeterminate; 
            }
            set
            {
                if (value != isIndeterminate)
                {
                    isIndeterminate = value;
                    RaisePropertyChanged(nameof(IsIndeterminate));
                    RaisePropertyChanged(nameof(State));
                }
            }
        }
        

        public int Percent
        {
            get
            {
                return percent; 
            }
            set
            {
                if (value != percent)
                {
                    percent = value;
                    RaisePropertyChanged(nameof(Percent));
                    RaisePropertyChanged(nameof(Count));
                }
            }
        }

        public double Count
        {
            get 
            {
                count = Percent / 100d;
                return count;
            }
        }


        private bool CanStart()
        {
            return true;
        }

        private async void OnStart()
        {
            IsEnabled = false;
            Percent = 0;
            
            await Task.Run(() =>
            {
                while (Percent != 100)
                {
                    Thread.Sleep(100);
                    Percent  = 2;
                    
                }

                IsIndeterminate = true;
                Thread.Sleep(5000);
                IsIndeterminate = false;
            });

            IsEnabled = true;

        }
    }
}
  

BoulToProgressStateConverter.cs

 using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Shell;

namespace ProgressState
{
    class BoolToProgressStateConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool boolean)
            {
                if (boolean == true)
                {
                    return TaskbarItemProgressState.Indeterminate;
                }
                else if (boolean == false)
                {
                    return TaskbarItemProgressState.Normal;
                }
                else
                {
                    throw new NotImplementedException();
                }

            }
            return TaskbarItemProgressState.Normal;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
  

Есть идеи?

Комментарии:

1. Я использую точно такую же конфигурацию, что и ваша, но с . NET v4.6.1. После переконфигурирования его для использования v4.7.2 (и 4.8) я по-прежнему ничего не получаю на панели задач… По крайней мере, я знаю, что сам код работает. Спасибо за ваше время…

2. Я бы попробовал запустить ваш пример кода на другом компьютере, чтобы подтвердить, что это может быть проблема с вашей системой. Удачи!

3. Я только что попробовал это на машине коллеги, и все работает нормально. Я сделаю еще один комментарий, если мне удастся выяснить, в чем проблема с моей машиной… Еще раз спасибо!

4. Я столкнулся с той же проблемой, моя среда — Win10 WPF .Net5. Оба моих проекта будут делать это, один из проектов, похоже, время от времени работает нормально, и у меня создается впечатление, что это какая-то ошибка.

5. У меня была эта проблема с RDP. По-видимому, есть некоторые оптимизации, которые предотвращают отображение «пульсирования».