2015-05-28 2 views
0

Следуя примеру книги «Разработка WPF Control Unleashed», я модифицировал ProgressBar, чтобы вместо этого отобразить круговой таймер. Это содержит дугу, которая вращается против часовой стрелки вокруг центра окна (в зависимости от значения моего ProgressBar).UIElement.Rendersize не уменьшает масштаб окна при изменении размера окна

Мои Arc -класс наследует от System.Windows.Shapes.Shape и я использую RenderSize.Width и RenderSize.Height Свойства, чтобы масштабировать его в зависимости от моего Windowsize.

Это, казалось, сработало нормально, но визуализация только кажется увеличение. Таким образом, моя дуга отлично масштабируется, когда я расширяю окно, содержащее ProgressBar, но когда я уменьшаю его размер, размер дуги не уменьшается.

My ControlTemplate содержит сетку, в которой настроены все элементы (включая дугу), поэтому все остальные элементы, которые не зависят напрямую от RenderSize (некоторые эллипсы и текстовые блоки), масштабируются вверх и вниз по желанию.

Есть ли у вас идеи, почему RenderSize ведет себя так, как описано, и какие значения я мог бы использовать вместо этого для вычисления координат x/y начала/конца дуги?

Примечание: если я установить width и height сетки к фиксированному значению, RenderSize не меняется на все, что сбивает с толку меня еще больше, так как эллипсов и текстовое поле шкалы соответственно уже в сетке.

ответ

0

Я сам сделал раунд, но я вообще не использовал RenderSize.

Лучший подход заключается в определении свойства InnerRadius и OuterRadius на вашем д'Арк, и пусть их значения между 0 и 1.

Затем сделать расчеты в DefiningGeometry переопределения дуги.

Поскольку Arc представляет собой форму, вы можете использовать его свойство Stretch, чтобы масштабировать его внутри элемента управления.

Одна из проблем с масштабированием является то, что ограничивающий прямоугольник дуги изменяется с его значением/угла. Вот почему вам нужно определить EllipseGeometry внутри DefiningGeometry, чтобы зафиксировать границы Arc. И из-за этой дополнительной геометрии я даже добавил вторую EllipseGeometry, чтобы получить правильное заполнение (из-за значения FillRule.EvenOdd).

Удачи вам!

+0

звуки действительны до сих пор, но как вы определяете InnerRadius и OuterRadius, не зная размер ограничивающей рамки? Это то, что я использовал RenderSize для. –

+0

Вы используете нормированные координаты/радиусы, например, InnerRadius = 0,9, OuterRadius = 1.Настройка Stretch = Uniform on the Arc автоматически масштабирует ее родительскую. –

+0

Но я должен признать, что в прошлом у меня было несколько проблем с масштабированием с помощью Shapes, иногда они становились слишком большими, пока я не закодировал их ширину/высоту. Не уверен, когда это произойдет. Если вы установите ширину и высоту на самой Progressbar, вы должны быть в порядке. –

2

Я также прочитал книгу «Развитие управления WPF Unleashed». И посмотрите на масштабный масштаб управления часами. Проблема заключается в том, что RenderSize не изменился, когда окно изменило свой размер. Мое решение добавляет некоторую логику в метод ArrangeOverride и MessureOverride.

private Size _finalSize; 

    protected override Size MeasureOverride(Size availableSize) 
    { 
     Debug.WriteLine(string.Format("Mesure:{0},{1}", availableSize.Width, availableSize.Height)); 
     Size desiredSize = base.MeasureOverride(availableSize); 
     _finalSize = availableSize; 
     return desiredSize; 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     Debug.WriteLine(string.Format("Arrange:{0},{1}", _finalSize.Width, _finalSize.Height)); 
     base.ArrangeOverride(_finalSize); 
     return _finalSize; 
    } 

=========================================== ============================== Я прочитал некоторые materials.They сказал Messure и Устройте могут иметь такую ​​же логику, но они не должны делиться данные. К счастью, я нахожу другое решение. Во-первых, элемент управления должен иметь свойство зависимости растяжки. А затем измените метод ArcGeometry.

static Arc() 
    { 
     StretchProperty.OverrideMetadata(typeof(Arc), new FrameworkPropertyMetadata(Stretch.Fill)); 
    } 

    private Geometry GetArcGeometry2() 
    { 
     Point startPoint = PointAtAngle(RenderSize, Math.Min(StartAngle, EndAngle)); 
     Point endPoint = PointAtAngle(RenderSize, Math.Max(StartAngle, EndAngle)); 
     Point stopPoint = PointAtAngle(RenderSize, Math.Max(EndAngle, 359.99));//Add this 

     Size arcSize = new Size(Math.Max(0, (RenderSize.Width - StrokeThickness)/2), 
           Math.Max(0, (RenderSize.Height - StrokeThickness)/2)); 
     bool isLargeArc = Math.Abs(EndAngle - StartAngle) > 180; 

     StreamGeometry geom = new StreamGeometry(); 
     using (StreamGeometryContext context = geom.Open()) 
     { 
      context.BeginFigure(startPoint, false, false); 
      context.ArcTo(endPoint, arcSize, 0, isLargeArc, SweepDirection.Counterclockwise, true, false); 
      context.ArcTo(stopPoint, arcSize, 0, !isLargeArc, SweepDirection.Counterclockwise, false, false);//add blank arc 
     } 

     geom.Transform = new TranslateTransform(StrokeThickness/2, StrokeThickness/2); 
     return geom; 
    } 
+0

Только сообщения, которые проверяются, тестируются и работают. Ответ, который не работает, будет довольно быстро получать downvotes. –

Смежные вопросы