Как использовать диспетчер для обновления панели прогресса в WPF [дубликат]

Другим сценарием является то, что вы нанесли нулевой объект в тип значения . Например, код ниже:

object o = null;
DateTime d = (DateTime)o;

Он выкинет NullReferenceException в роли. В приведенном выше примере это кажется совершенно очевидным, но это может произойти в более «поздних связующих» сложных сценариях, где нулевой объект был возвращен из некоторого кода, которого вы не являетесь, и приведение, например, генерируется некоторой автоматической системой.

Одним из примеров этого является этот простой фрагмент привязки ASP.NET с элементом управления календарем:

" />

Здесь SelectedDate на самом деле является свойством - типа DateTime - типа Calendar Web Control, и привязка может отлично вернуть что-то null. Неявный генератор ASP.NET создаст кусок кода, который будет эквивалентен приведенному выше методу. И это поднимет NullReferenceException, что довольно сложно определить, потому что он лежит в сгенерированном ASP.NET коде, который компилирует отлично ...

32
задан jpgooner 19 August 2010 в 10:24
поделиться

3 ответа

Как правило, ваш пользовательский интерфейс будет просто привязываться к свойствам вашей виртуальной машины:

<ProgressBar Value="{Binding CurrentProgress, Mode=OneWay}" 
             Visibility="{Binding ProgressVisibility}"/>

Ваша виртуальная машина будет использовать BackgroundWorker для работы над фоновым потоком и для периодического обновления значения CurrentProgress. Что-то вроде этого:

public class MyViewModel : ViewModel
{
    private readonly BackgroundWorker worker;
    private readonly ICommand instigateWorkCommand;
    private int currentProgress;

    public MyViewModel()
    {
        this.instigateWorkCommand = 
                new DelegateCommand(o => this.worker.RunWorkerAsync(), 
                                    o => !this.worker.IsBusy);

        this.worker = new BackgroundWorker();
        this.worker.DoWork += this.DoWork;
        this.worker.ProgressChanged += this.ProgressChanged;
    }

    // your UI binds to this command in order to kick off the work
    public ICommand InstigateWorkCommand
    {
        get { return this.instigateWorkCommand; }
    }

    public int CurrentProgress
    {
        get { return this.currentProgress; }
        private set
        {
            if (this.currentProgress != value)
            {
                this.currentProgress = value;
                this.OnPropertyChanged(() => this.CurrentProgress);
            }
        }
    }

    private void DoWork(object sender, DoWorkEventArgs e)
    {
        // do time-consuming work here, calling ReportProgress as and when you can
    }

    private void ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.CurrentProgress = e.ProgressPercentage;
    }
}
54
ответ дан Akram Shahda 1 September 2018 в 02:41
поделиться

Добавьте два свойства к вашей виртуальной машине:

bool IsProgressBarVisible
double ProgressValue

Если вы запустите длительную операцию в своей виртуальной машине, установите для свойства IsProgressBarVisible значение true и установите периодичность ProgressValue на текущее значение прогресса. Попробуйте вычислить значение от 0 до 100. Это имеет то преимущество, что вам не нужно предоставлять минимальное и максимальное значение. После завершения асинхронной операции установите для параметра IsProgressBarVisible значение false.

В XAML свяжите эти два свойства. Используйте конвертер значений, чтобы преобразовать булевскую видимость в видимость.

<ProgressBar Value="{Binding ProgressValue}" Visibility="{Binding IsProgressBarVisible,Converter={StaticResource BooleanToVisibility_ValueConverter}}"/> 
6
ответ дан HCL 1 September 2018 в 02:41
поделиться

Используйте элемент управления ProgressBar и привяжите его свойство Value к свойству ViewModel:

View

<ProgressBar Minimum="0" Maximum="0" Value="{Binding CurrentProgress}" />

ViewModel

private double _currentProgress;
public double CurrentProgress
{
    get { return _currentProgress; }
    private set
    {
        _currentProgress = value;
        OnPropertyChanged("CurrentProgress");
    }
}
8
ответ дан Thomas Levesque 1 September 2018 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: