I am stuck. I want to do some sophisticated animations in XAML, in which the geometry of the image gets modified at runtime. I want to start out simple, and then make something far more interesting, but nothing seems to work. For now, all I want to do is draw an arc on the screen using a for-loop, and this arc will be modified by a slider. The slider will control the starting point of the arc. So, if I have the slider at Pi/4, it will draw an arc from Pi/4 to 2Pi.
I've tried so many different ways. Right now I've created a class of the type Shape
, and tried to modify the DefiningGeometry
which is a property of the Shape
class. The startRadians
gets modified by the slider, so that part works OK, I got the binding to work. But, after startRadians
gets changed (it is a DependencyProperty
, btw) I want the class to re-calculate the geometry of the circle. (Like a cherry pie that is missing a bigger piece as startRadians
gets changed.) The real problem is that DefiningGeometry
is a read-only property, so I can't change it on the fly. (Am I right about this?) Even if I could, I don't know the way to write the line of code so that DrawMyArc
fires again, and the results get reloaded into DefiningGeometry
.
OK, so I need some guidance. Should I change the parent class, so that I have an easily modifiable Path/geometry? I am at a loss here.
Should I use an entirely different approach, like where you dynamically make/delete the geometry using StreamGeometry?
Here's the relevant code:
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace January14noon
{
public class myCircle : Shape
{
public double startRadians
{
get { return (double)GetValue(startRadiansProperty); }
set { SetValue(startRadiansProperty, value); }
}
protected override Geometry DefiningGeometry
{
get
{
return DrawMyArc(100, 200, true, 40, 40, 360, startRadians, 2 * Math.PI);
}
}
// Using a DependencyProperty as the backing store for startRadians. This enables animation, styling, binding, etc...
public static readonly DependencyProperty startRadiansProperty =
DependencyProperty.Register("startRadians", typeof(double), typeof(myCircle), new PropertyMetadata(Math.PI / 4, new PropertyChangedCallback(startRadians_PropertyChanged)));
private static void startRadians_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//
//
}
public PathGeometry DrawMyArc(double centX, double centY, bool CW, double radiusX, double radiusY, int numberOfSegs, double startRad, double endRad)
{
double[,] rawPoints = new double[numberOfSegs, 2];
List<LineSegment> segments = new List<LineSegment>();
double arcLength;
arcLength = endRad - startRad;
for (int i = 0; i < numberOfSegs; i++)
{
rawPoints[i, 0] = radiusX * Math.Sin(i * (arcLength / numberOfSegs) + startRad) + centX;
rawPoints[i, 1] = radiusY * -Math.Cos(i * (arcLength / numberOfSegs) + startRad) + centY;
segments.Add(new LineSegment(new Point(rawPoints[i, 0], rawPoints[i, 1]), true));
}
LineSegment[] segArray = segments.ToArray();
PathFigure figure = new PathFigure(new Point(centX, centY), segments, false);
PathGeometry myGeometry = new PathGeometry();
myGeometry.Figures.Add(figure);
return myGeometry;
}
}
}
And XAML:
<Window x:Class="January14noon.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:January14noon"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:myCircle x:Key="myCircleDataSource" d:IsDataSource="True"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource myCircleDataSource}}">
<Slider x:Name="slider" VerticalAlignment="Top" Margin="0,0,163.898,0" Value="{Binding startRadians, Mode=OneWayToSource}"/>
<TextBox x:Name="myTextBox" HorizontalAlignment="Right" Height="23" TextWrapping="Wrap" Text="{Binding startRadians}" VerticalAlignment="Top" Width="147.797"/>
<!--<local:myCircle x:Name="instanceOfCircle" />-->
<local:myCircle Stroke="Black" StrokeThickness="2"/>
</Grid>
</Window>
Any help would be appreciated. Just general approach, something specific even words of encouragement.
TYIA
2条答案
按热度按时间u5rb5r591#
Any dependency property that affects visual appearance of a control might be registered with appropriate
FrameworkPropertyMetadataOptions
, e.g.AffectsMeasure
,AffectsArrange
orAffectsRender
.Note also that class, property and method names in C# are supposed to use Pascal Casing, i.e. start with an uppercase letter
lkaoscv72#
确保将可见圆绑定到数据源:
并在属性更改时使视觉对象无效:
无效操作将通知引擎重新呈现此视觉效果,这将调用您
DrawMyArc()
方法