Как заполнить прямоугольник некоторыми цветами, используя градиент, но только как инструмент (без видимого градиента)? - PullRequest
0 голосов
/ 22 декабря 2018

Я делаю конвертер для свойства «Заполнить» прямоугольника, чтобы заполнить его разными цветами.

Итак, у меня есть список информации о датах отсутствия человека.Различные части прямоугольника должны быть заполнены color1, если человек отсутствовал в периоде, и color2 в противном случае.Для каждого человека в FOR я вычисляю разницу между датами и заполняю градиентные остановки следующим образом: color1-border-color2-border-color1 ... Я пытаюсь сделать границу почти невидимой.

Конвертер:

 double bufferOffset = 0.0;
 double taskPeriodInDays = (endDate.Value.Date - 
 startDate.Value.Date).TotalDays;
 List<double> timeSections = new List<double>();

 for (int i = 1; i < absencesDatesBetweenStartAndEnd.Count; i++)
    {
       IsAbsent = !IsAbsent;
       GradientStop color = new GradientStop();
       GradientStop border = new GradientStop();
       border.Color = Colors.Black;

   color.Color = IsAbsent ? Colors.Orange : Colors.Violet;


   color.Offset = i == 1 ? 0 : bufferOffset;
   gradient.GradientStops.Add(color);

   color.Offset = bufferOffset + (absencesDatesBetweenStartAndEnd[i].Date - absencesDatesBetweenStartAndEnd[i - 1].Date).TotalDays / taskPeriodInDays;
   gradient.GradientStops.Add(color);

  if(i == absencesDatesBetweenStartAndEnd.Count - 1)
   {
      break;
   }

        border.Offset = color.Offset + 0.00001;
        gradient.GradientStops.Add(border);

        border.Offset = border.Offset + 0.00001;
        gradient.GradientStops.Add(border);

        bufferOffset = border.Offset;
   }
   return gradient;

<Rectangle Fill="{Binding Converter={StaticResource TaskExecutorAbsenceColorConverter}}"/>

Жесткое кодирование XAML для пробных значений:

<Rectangle.Fill>
   <LinearGradientBrush StartPoint="0 0" EndPoint="1 0">
      <GradientStop Color="red" Offset="0"/>
      <GradientStop Color="red" Offset="0.065573770491803282"/>
      <GradientStop Color="black" Offset="0.065583770491803278"/>
      <GradientStop Color="black" Offset="0.065593770491803274"/>
      <GradientStop Color="blue" Offset="0.065593770491803274"/>
      <GradientStop Color="blue" Offset="0.29510196721311477"/>
      <GradientStop Color="black" Offset="0.29511196721311478"/>
      <GradientStop Color="black" Offset="0.29512196721311479"/>
      <GradientStop Color="red" Offset="0.29512196721311479"/>
      <GradientStop Color="red" Offset="0.36069573770491808"/>
      <GradientStop Color="black" Offset="0.36070573770491809"/>
      <GradientStop Color="black" Offset="0.3607157377049181"/>
      <GradientStop Color="blue" Offset="0.3607157377049181"/>
      <GradientStop Color="blue" Offset="0.50825672131147548"/>
      <GradientStop Color="black" Offset="0.50826672131147543"/>
      <GradientStop Color="black" Offset="0.50827672131147539"/>
      <GradientStop Color="red" Offset="0.50827672131147539"/>
      <GradientStop Color="red" Offset="1.00008"/>
   </LinearGradientBrush>
</Rectangle.Fill>

Преобразователь работает неправильно.Градиент виден.

Как видите, я пытался поместить значения градиентов в XAML, в этом случае он прекрасно работает.Я не понимаю, почему.

Значения жесткого кодирования в XAML Использование конвертера

1 Ответ

0 голосов
/ 24 декабря 2018

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

public class Conv : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        VisualBrush result = new VisualBrush();
        result.Stretch = Stretch.Fill;
        StackPanel container = new StackPanel();
        container.Orientation = Orientation.Horizontal;

        //Generate a colored rectangle for each day.
        //I just use some random values for illustration.
        Random rnd = new Random();
        for (int i = 0; i < 10; i++)
        {
            Rectangle rect = new Rectangle();
            rect.Width = 20;
            rect.Height = 20;
            rect.Fill = rnd.Next() % 2 == 0 ? Brushes.Red : Brushes.Green;
            container.Children.Add(rect);
        }
        result.Visual = container;
        return result;
    }

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