Почему мой индикатор не работает? - PullRequest
2 голосов
/ 13 июля 2009

Я не могу заставить мой индикатор выполнения работать. Любая помощь очень ценится!

Вот код:

<Window x:Class="BulkSAConfigureControl.BulkSaProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Please Wait.." Height="60" Width="300" WindowStyle="ToolWindow" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<ProgressBar Name="progressBar" IsIndeterminate="True">
    <ProgressBar.Resources>
        <ResourceDictionary Source="/PresentationFramework.Aero;v3.0.0.0;31bf3856ad364e35;component/themes/aero.normalcolor.xaml" />
    </ProgressBar.Resources>
</ProgressBar>

.

public class ProgressBarClass : Window
{   
    public ProgressBarClass()
    {
        InitializeComponent();
    }

    public void StartProgressBar()
    {
        Duration d = new Duration(TimeSpan.FromSeconds(5));
        DoubleAnimation anim = new DoubleAnimation(100.0, d);
        progressBar.BeginAnimation(ProgressBar.ValueProperty, anim);
        this.Show();
    }

    public void StopProgressBar()
    {
        this.Close();
    }
}

.

public class DoSomething : UserControl
{
    public void DoSomeStuff()
    {
        ProgressBarClass pBar = new ProgressBarClass();
        pBar.StartProgressBar();

        // Do some stuff here

        pBar.StopProgressBar();
    }
}

Ответы [ 5 ]

3 голосов
/ 13 июля 2009

Чтобы добавить то, что говорит Марк, есть два способа решения проблемы. Взломать путь и правильный путь.

Правильный способ - использовать многопоточность, например, BackgroundWorker. Вы, вероятно, в конечном итоге будете использовать control.BeginInvoke для обработки обновления потока графического интерфейса.

Способ взлома - вызвать Application.DoEvents в вашем цикле. Я называю это хаком, потому что он работает только частично. Например, если вы делаете узкий цикл, который содержит много маленьких быстрых инструкций, тогда он будет работать нормально. Если вы выполняете цикл, в котором ваши инструкции занимают некоторое время, это не сработает (например, при выполнении огромного SQL-запроса к базе данных).

Здесь - хорошая ссылка, чтобы узнать об этом конкретном примере. Я думаю, что WPF работает немного иначе, чем обычные WinForms.

1 голос
/ 14 июля 2009

Я заметил две вещи:

  • Если вы установите IsIndeterminate = "True" для индикатора выполнения, он не будет перемещаться от 0 до 100%, а просто будет бегать влево-вправо-влево снова и снова (некоторый эффект KITT), вы захотите это, только если вы не наденете Не знаю, где вы находитесь в вашем графике прогресса. (с некоторыми стилями вы даже ничего не видите на индикаторе выполнения, но в Vista-default он показывает некоторый зеленый оттенок, переходящий из стороны в сторону)
  • Если вы хотите установить значение прогресса из фонового потока, вы должны сделать это, используя фонового работника для своего действия, а затем использовать метод, называемый «ReportProgress», после определенных этапов. Таким образом, пользовательский интерфейс выполнит обновление, чтобы показать ваш новый прогресс.
1 голос
/ 14 июля 2009

Я не уверен, что это ваша проблема (я не знаю много об анимации ... Я использовал индикатор выполнения только путем увеличения свойства "Value"), но я думаю, что большинство предложений здесь игнорировать модель потоков пользовательского интерфейса, представленную в WPF: Потоки в WPF

Если у вас есть какой-то цикл (я не думаю, что вы делаете, судя по вашему коду, но я могу ошибаться), тогда вы захотите запланировать каждую итерацию вашего цикла с помощью Dispatcher ... таким образом, WPF может распределять ваш код, выполняя события пользовательского интерфейса, необходимые для перерисовки.

Надеюсь, это поможет.

1 голос
/ 13 июля 2009

Этот ответ относится не только к C # или WPF, но к Windows в целом. Индикатор выполнения будет обновляться только при обработке сообщений Windows. Если вы работаете в тесном цикле ЦП без взаимодействия с пользовательским интерфейсом, индикатор выполнения никогда не сможет перекраситься.

0 голосов
/ 14 июля 2009

Я полагаю, что вы задаете основной вопрос о том, как заставить индикатор выполнения работать из кода? и Threading не ваша проблема, я думаю. В WPF очень просто заставить работать индикатор выполнения. Надеюсь, что у вас будут какие-то значения из вашего фонового процесса в процентах или около того. Просто установите свойство ProgressBar.Value, и он сделает все остальное. Тестовое приложение ниже

<ProgressBar x:Name="progress" MouseDown="Window_MouseDown" VerticalAlignment="Top" Height="93"/>

на C #

    private void Window_MouseDown(object sender, MouseButtonEventArgs e)
    {
        progress.Value = progress.Value+1;
    }

И напишите следующий код в коде позади и продолжайте нажимать на ProgressBar, когда приложение работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...