Hi Moondaddy,
I downloaded your sample project and run it and did see the problem on my
side.
There're three problems in the source code of your project.
1. You should move the following lines of code from the GetGeometry method
within the CustomPolyLine class:
_points.Add(new Point(10, 10));
_points.Add(new Point(10, 100));
_points.Add(new Point(100, 100));
Because while the application is running, the override DefiningGeometry
method will be called for several times which in turn calls the GetGeometry
method, there will be more than 3 points added to the _points collection.
You can move the above lines of code to the constructor of the
CustomPolyLine class.
2. To get a custom shape to refresh in UI automatically when the value of
properties of the custom shape are changed at run time, you need to back
the CLR properties with dependency properties. For example:
public PointCollection Points
{
get
{
return (PointCollection )base.GetValue(PointsProperty);
}
set
{
base.SetValue(PointsProperty,value);
}
}
public static readonly DependencyProperty PointsProperty =
DependencyProperty.Register("PointsProperty",
typeof(PointCollection), typeof(CustomPolyLine), new
FrameworkPropertyMetadata(new PointCollection() { new Point(10, 10), new
Point(10, 100), new Point(100, 100) },
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure));
NOTE: Only when the value of a dependency property is changed, the instance
will be refreshed in UI. As for the Points property in the above sample
code, the PointCollection is a reference type. Only when the Points
property is set to a new instance of type PointCollection, the custom shape
will refresh in UI.
In other words, if you add a Point object to the Points property, the
custom shape won't refresh in UI because the value of the Points property
is not changed(it still refers to the same object as before).
3. To workaround the problem, we can use ObservableCollection<Ttype
instead of the PointCollection type because the ObservableCollection<T>
provides list changes notification. Then subscribe the CollectionChanged
event to refresh the custom shape in UI manually. The following is the
complete modified code of the CustomPolyLine class.
public class CustomPolyLine : Shape
{
public CustomPolyLine()
{
// subscribe the CollectionChanged event of the Points property
Points.CollectionChanged += Points_CollectionChanged;
}
void Points_CollectionChanged(object sender,
System.Collections.Specialized.NotifyCollectionCha ngedEventArgs e)
{
// invalidate the custom shape manually
base.InvalidateMeasure();
}
// use the type of ObservableCollection<Pointinstead of
PointCollection, because ObservableCollection<Pointprovides list changes
notification
public ObservableCollection<PointPoints
{
get
{
return
(ObservableCollection<Point>)base.GetValue(PointsP roperty);
}
set
{
base.SetValue(PointsProperty,value);
}
}
public static readonly DependencyProperty PointsProperty =
DependencyProperty.Register("PointsProperty",
typeof(ObservableCollection<Point>), typeof(CustomPolyLine), new
FrameworkPropertyMetadata(new ObservableCollection<Point>() { new Point(10,
10), new Point(10, 100), new Point(100, 100) },
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure));
protected override Geometry DefiningGeometry
{
get
{
// Create a StreamGeometry for describing the shape
StreamGeometry geometry = new StreamGeometry();
geometry.FillRule = FillRule.EvenOdd;
using (StreamGeometryContext context = geometry.Open())
{
GetGeometry(context);
}
// Freeze the geometry for performance benefits
geometry.Freeze();
return geometry;
}
}
void GetGeometry(StreamGeometryContext context)
{
context.BeginFigure(Points[0], true, false);
foreach (Point pt in Points)
{
context.LineTo(pt, true, true);
}
}
}
Hope this helps.
If you have any question, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.