Прогрессбар, который меняет стиль на основе процента выполнения - PullRequest
2 голосов
/ 20 января 2012

Я новичок в WPF и пока не смог найти решение этой проблемы.

Мы пытаемся создать UserControl, который предоставляет индикатор выполнения, который будет менять свой стиль при увеличении процентного соотношения (в основном красный, когда он составляет менее 50%, желтый до 30% и т. Д.)

Кажется, что элемент управления работает отлично для обновления стиля. Когда окно открывается впервые, значение всегда равно 0, даже если индикатор выполнения запускается с 50% или около того. Мне кажется, я испортил код PropertyChanged или не связал данные где-то прямо. Вот код на данный момент:

XAML-файл, использующий UserControl (TaskListStatus.xaml)

    <ssw:ColoredProgressBar x:Name="pbCompleted" Value="{Binding PercentCompleted}" Height="40"/>

ColoredProgressBar.xaml:

    <UserControl.Resources>
        <this:ProgressBarStyleConverter x:Key="pbStyleConverter"/>
        <!-- Progress Bar Styles-->
        ........
    </UserControl.Resources>
    <Grid>
        <ProgressBar x:Name="pb" Value="{Binding Path=Value, ElementName=coloredBar}">
            <ProgressBar.Style>
                <Binding Converter="{StaticResource pbStyleConverter}"
                        RelativeSource="{RelativeSource Self}"/>
            </ProgressBar.Style>
        </ProgressBar>
    </Grid>

ColoredProgressBar.xaml.cs

    public partial class ColoredProgressBar : UserControl, INotifyPropertyChanged {
        public ColoredProgressBar() {
            InitializeComponent();
        }
        public static DependencyProperty ValueProperty =
                  DependencyProperty.Register("Value", typeof(double),
                  typeof(ColoredProgressBar), new PropertyMetadata(null));
        public double Value {
            get { return Convert.ToDouble(GetValue(ValueProperty)); }
            set {
                SetValue(ValueProperty, value);
                if (PropertyChanged != null) {
                    PropertyChanged(this, new PropertyChangedEventArgs("Value"));
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

ProgressBarStyleConverter.cs

    public class ProgressBarStyleConverter : IValueConverter {
        private const int RED_CUTOFF = 40;
        private const int YELLOW_CUTOFF = 100;
        private enum ProgressBarColor {
            Green,
            Yellow,
            Red
        }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            FrameworkElement targetElement = value as FrameworkElement;
            double progressBarValue = ((ProgressBar)targetElement).Value;
            string styleName = "AeroProgressBarStyle";
            ProgressBarColor color;
            if (progressBarValue < RED_CUTOFF) {
                color = ProgressBarColor.Red;
            } else if (progressBarValue < YELLOW_CUTOFF) {
                color = ProgressBarColor.Yellow;
            } else {
                color = ProgressBarColor.Green;
            }
            switch (color) {
                case ProgressBarColor.Green:
                    styleName = "AeroProgressBarStyle"; break;
                case ProgressBarColor.Yellow:
                    styleName = "YellowAeroProgressBarStyle"; break;
                case ProgressBarColor.Red:
                    styleName = "RedAeroProgressBarStyle"; break;
            }
            return (Style)targetElement.TryFindResource(styleName);
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            return null;
        }
    }

Если кто-то может помочь, это будет очень признательно.

Ответы [ 2 ]

1 голос
/ 31 января 2012

Пока что так мы добились его работы. Я не уверен на 100%, что это идеальный способ, но он работает:

ColoredProgressBar.xaml:

    <UserControl.Resources>
        <this:ProgressBarStyleConverter x:Key="pbStyleConverter"/>
        <!-- Progress Bar Styles-->
        ........
    </UserControl.Resources>
    <Grid>
        <ProgressBar x:Name="pb" Value="{Binding Path=Value, ElementName=coloredBar}">
            <ProgressBar.Style>
                <MultiBinding Converter="{StaticResource pbStyleConverter}">
                    <Binding RelativeSource="{RelativeSource Self}" />
                    <Binding ElementName="coloredBar" Path="Value" />
                </MultiBinding>
            </ProgressBar.Style>
        </ProgressBar>
    </Grid>

Мы не могли понять, как связать привязку с одной привязкой. Причина, по которой мы должны перейти в Себе, заключается в том, что именно здесь все храмы определены для настройки цвета. Я попытался передать Self в качестве ConverterParameter, но я никогда не мог заставить его работать. Таким образом, передав его как MultiBinding, мы можем добраться до себя и храмов, определенных там, и поскольку значение передается, когда значение обновляется, оно обновляет храм индикатора выполнения.

0 голосов
/ 20 января 2012

Свяжите стиль со свойством Value объекта ProgressBar, а не самого ProgressBar.Поэтому добавьте атрибут Path = Value в привязку и измените код преобразователя соответствующим образом.

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