WPF / Windows 7: отключить анимацию подсветки индикатора выполнения по умолчанию

Быстрый вопрос по WPF - в Win 7 (и я предполагаю, что в Vista) в WPF индикатор выполнения по умолчанию делает красивую маленькую светящуюся "свистящую" -у-анимацию.

Я показываю прогресс примерно 48 вещей на одном экране, и это немного ошеломляет, когда все эти вещи свистят на вас - можете ли вы отключить только эти анимации, не затрагивая остальные анимации по умолчанию в приложении?


person Brandon    schedule 06.10.2009    source источник
comment
@Matthew, что не так в отображении 48 индикаторов выполнения? Вы видели кабину самолета? или приборная панель метеоролога? или приборной панели любого станка с ЧПУ? не каждое приложение предназначено только для программистов и только для ИТ-менеджеров, я думаю, что ответ должен иметь отношение к вопросу, а не предлагать человеку изменить свой дизайн, он выполняет свою работу и не задавал вопросов, например, хорошо ли иметь 48 достижений бары?   -  person Akash Kava    schedule 06.10.2009
comment
@Matthew, в этом приложении уместно 48 индикаторов выполнения, поскольку оно отображает информацию о 48 устройствах, которые физически контролируются в режиме реального времени. Я бы согласился с вами, если бы это было LOB-приложение или что-то в этом роде.   -  person Brandon    schedule 06.10.2009


Ответы (6)


Я согласен с комментарием Мэтью, но в любом случае ваш ответ - применить собственный стиль без анимации. Вот оригинальный стиль (через отражатель), вы можете удалить / настроить / что угодно:

<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
    <Style.Triggers>
        <Trigger Property="Orientation" Value="Vertical">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ProgressBar}">
                        <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
                            <Border BorderThickness="1,1,1,0" BorderBrush="#BEBEBE" CornerRadius="2">
                                <Border BorderThickness="1" BorderBrush="#EFEFEF" CornerRadius="1">
                                    <DockPanel Name="PART_Track" Margin="0,0,0,1" LastChildFill="false">
                                        <Decorator Name="PART_Indicator" Dock="Bottom">
                                            <Rectangle LayoutTransform="{RotateTransform Angle=-90}">
                                                <Rectangle.Fill>
                                                    <MultiBinding Converter="{theme:ProgressBarBrushConverter}">
                                                        <Binding Path="Foreground" RelativeSource="{RelativeSource TemplatedParent}" />
                                                        <Binding Path="IsIndeterminate" RelativeSource="{RelativeSource TemplatedParent}" />
                                                        <Binding Path="ActualHeight" ElementName="PART_Indicator" />
                                                        <Binding Path="ActualWidth" ElementName="PART_Indicator" />
                                                        <Binding Path="ActualHeight" ElementName="PART_Track" />
                                                    </MultiBinding>
                                                </Rectangle.Fill>
                                            </Rectangle>
                                        </Decorator>
                                    </DockPanel>
                                </Border>
                            </Border>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
    <Setter Property="Foreground" Value="{StaticResource [0] Ñ}" />
    <Setter Property="Background" Value="{DynamicResource {x:Static WindowBrush}}" />
    <Setter Property="BorderBrush" Value="#686868" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
                    <Border BorderThickness="1,1,1,0" BorderBrush="#BEBEBE" CornerRadius="2">
                        <Border BorderThickness="1" BorderBrush="#EFEFEF" CornerRadius="1">
                            <DockPanel Name="PART_Track" Margin="1,0,0,1" LastChildFill="false">
                                <Rectangle Name="PART_Indicator">
                                    <Rectangle.Fill>
                                        <MultiBinding Converter="{theme:ProgressBarBrushConverter}">
                                            <Binding Path="Foreground" RelativeSource="{RelativeSource TemplatedParent}" />
                                            <Binding Path="IsIndeterminate" RelativeSource="{RelativeSource TemplatedParent}" />
                                            <Binding Path="ActualWidth" ElementName="PART_Indicator" />
                                            <Binding Path="ActualHeight" ElementName="PART_Indicator" />
                                            <Binding Path="ActualWidth" ElementName="PART_Track" />
                                        </MultiBinding>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </DockPanel>
                        </Border>
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

И класс преобразователя:

public class ProgressBarBrushConverter : IMultiValueConverter
{
// Methods
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    Type type = typeof(double);
    if (((((values == null) || (values.Length != 5)) || ((values[0] == null) || (values[1] == null))) || (((values[2] == null) || (values[3] == null)) || ((values[4] == null) || !typeof(Brush).IsAssignableFrom(values[0].GetType())))) || ((!typeof(bool).IsAssignableFrom(values[1].GetType()) || !type.IsAssignableFrom(values[2].GetType())) || (!type.IsAssignableFrom(values[3].GetType()) || !type.IsAssignableFrom(values[4].GetType()))))
    {
        return null;
    }
    Brush brush = (Brush) values[0];
    bool flag = (bool) values[1];
    double d = (double) values[2];
    double num2 = (double) values[3];
    double num3 = (double) values[4];
    if ((((d <= 0.0) || double.IsInfinity(d)) || (double.IsNaN(d) || (num2 <= 0.0))) || (double.IsInfinity(num2) || double.IsNaN(num2)))
    {
        return null;
    }
    DrawingBrush brush2 = new DrawingBrush();
    brush2.Viewport = brush2.Viewbox = new Rect(0.0, 0.0, d, num2);
    brush2.ViewportUnits = brush2.ViewboxUnits = BrushMappingMode.Absolute;
    brush2.TileMode = TileMode.None;
    brush2.Stretch = Stretch.None;
    DrawingGroup group = new DrawingGroup();
    DrawingContext context = group.Open();
    double x = 0.0;
    double width = 6.0;
    double num6 = 2.0;
    double num7 = width + num6;
    if (flag)
    {
        int num8 = (int) Math.Ceiling((double) (d / num7));
        double num9 = -num8 * num7;
        double num10 = d * 0.3;
        brush2.Viewport = brush2.Viewbox = new Rect(num9, 0.0, num10 - num9, num2);
        TranslateTransform transform = new TranslateTransform();
        double num11 = num8 * 100;
        DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
        animation.Duration = new Duration(TimeSpan.FromMilliseconds(num11));
        animation.RepeatBehavior = RepeatBehavior.Forever;
        for (int i = 1; i <= num8; i++)
        {
            double num13 = i * num7;
            animation.KeyFrames.Add(new DiscreteDoubleKeyFrame(num13, KeyTime.Uniform));
        }
        transform.BeginAnimation(TranslateTransform.XProperty, animation);
        brush2.Transform = transform;
        while ((x + width) < num10)
        {
            context.DrawRectangle(brush, null, new Rect(num9 + x, 0.0, width, num2));
            x += num7;
        }
        d = num10;
        x = 0.0;
    }
    while ((x + width) < d)
    {
        context.DrawRectangle(brush, null, new Rect(x, 0.0, width, num2));
        x += num7;
    }
    double num14 = d - x;
    if ((!flag && (num14 > 0.0)) && (Math.Abs((double) (d - num3)) < 1E-05))
    {
        context.DrawRectangle(brush, null, new Rect(x, 0.0, num14, num2));
    }
    context.Close();
    brush2.Drawing = group;
    return brush2;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
    return null;
}
}
person Robert Fraser    schedule 06.10.2009
comment
Кто-нибудь действительно успешно использовал это? Я даже не могу скомпилировать вышеуказанный стиль. - person Allon Guralnek; 20.12.2011

Ответ Роберта убедителен. Вот хак (потому что он основан на внутреннем имени элемента, который делает свечение, что является деталью реализации и может измениться в следующей версии):

void SetGlowVisibility(ProgressBar progressBar, Visibility visibility) {
    var glow = progressBar.Template.FindName("PART_GlowRect", progressBar) as FrameworkElement;
    if (glow != null) glow.Visibility = visibility;
}

Если способ реализации индикатора выполнения изменится, этот хак может перестать работать.

С другой стороны, решение, которое полностью заменяет XAML и стили, может блокировать и исправлять цвета, границы и т. Д. И отключать поведение, которое может быть добавлено в более новую версию ProgressBar в будущем ...

person Mark Cranness    schedule 04.08.2011

Простой неанимированный индикатор выполнения можно записать в виде сетки с двумя заполненными прямоугольниками: левый будет заполнен, скажем, зеленым цветом, а правый - серым.

Сетка будет иметь два определения столбцов.

Изменение их ширины повлияет на изменение хода.

person bohdan_trotsenko    schedule 19.01.2010

Вы также можете полностью отключить этот эффект в Win7.

Щелкните правой кнопкой мыши значок «Мой компьютер» на рабочем столе и выберите «Свойства» (или нажмите клавишу Windows + Pause / Break), щелкните ссылку «Дополнительные параметры системы» на левой боковой панели (вы также можете открыть ее, набрав sysdm.cpl в меню «Пуск» или «Пуск». поле поиска и нажмите Enter). Теперь нажмите кнопку «Настройки» в разделе «Производительность»:

Снимите флажок «Анимировать элементы управления и элементы внутри окон», это должен быть первый выбор.

person dunecat    schedule 27.10.2009
comment
Спасибо, в этом конкретном случае он должен быть ограничен только приложением (не хочу полагаться на глобальное изменение темы ОС), но хорошая информация - person Brandon; 29.10.2009

Не в моей сфере, но этот ответ тоже может быть актуальным: Отключение прогресса барная анимация на Vista Aero

person seanf    schedule 14.03.2011

Создайте ярлык для используемого приложения, щелкните ярлык правой кнопкой мыши и выберите свойства. Теперь на вкладке совместимости установите флажок «отключить визуальные темы».

person SPrice    schedule 21.05.2012
comment
Это повлияет на другие анимации в приложении. - person Emond Erno; 20.10.2012