我正在嘗試使用ArcSegment將模型的一部分渲染爲半圓。我的代碼使用了許多基於2D Path的對象。除了使用ArcSegment的模塊外,所有工作都正常。例如,使用LineSegment的類似模塊可以正常工作。我無法呈現WPF ArcSegment。筆畫顏色不起作用
我可以看到我的ArcSegment的基本幾何圖形是正確的,因爲填充屬性通過填充預期半圓內的區域來使弧可見。
我沒有使用XAML。所有形狀都是使用C#/ WPF函數構建的。
以下是呈現所有使用WPF Path對象我的幾何對象的代碼:
// builder constructs a collection of Geometry objects and returns the in a GeometryGroup via ToGeometry()
GeometryGroup model2D = builder.ToGeometry();
model2D.Transform = BuildLocalTransform2D(visualModel);
var visual2D = new System.Windows.Shapes.Path();
if (typeof(Foundation.Visualisation.Elements2D.ShapeElement).IsAssignableFrom(visualModel.GetType()))
visual2D.Fill = ((Foundation.Visualisation.Elements2D.ShapeElement)visualModel).ShapeStyle.BackgroundBrush;
else
// ArcSegment and LineSegment based geometries always follow this path
// was using transparent but needed to add a color to make ArcSegment based Path visible
// the assignment to Stroke below does not work (line remains transparent) when model2D contains a PathGeometry that contains one ArcSegment
// I can see that the arc has the correct shape when the fill is not transparent
//visual2D.Fill = Brushes.Transparent;
visual2D.Fill = Brushes.Cyan;
// debug shows StrokeThickness is always 2
visual2D.StrokeThickness = ((PathElement)visualModel).LineStyle.LineThickness;
// debug shows that Stroke is always Brushes.Black
visual2D.Stroke = ((PathElement)visualModel).LineStyle.LineBrush;
visual2D.StrokeStartLineCap = PenLineCap.Round;
visual2D.StrokeEndLineCap = PenLineCap.Round;
visual2D.StrokeLineJoin = PenLineJoin.Round;
visual2D.Data = model2D;
WpfVisual2DProxy node = new WpfVisual2DProxy(visual2D, visualModel);
visualModel.AddProxy(node);
// the following adds the visual to an ItemsControl using a Canvas based template:
// this.ItemsPanel = new ItemsPanelTemplate(new FrameworkElementFactory(typeof(Canvas)));
((VisualContainer)((WpfVisual2DProxy)parentNode).Visual2D).AddChild(visual2D);
以下是我用來創建ArcSegment代碼:
public void AddArc(ModelPoint2D arcStart, ModelPoint2D arcEnd, double ellipseFactor, double degrees, bool isLarge, SweepDirection sweepDirection, LineVisualStyle lineStyle)
{
double radius = ellipseFactor * arcStart.Distance(arcEnd)/2.0;
List<ArcSegment> list = new List<ArcSegment>(2);
Point start = converter.ToPoint2D(arcStart);
list.Add(new ArcSegment(converter.ToPoint2D(arcEnd), new Size(radius, radius), Extrusion.DegreesToRadians(degrees), isLarge, SweepDirection.Clockwise, false));
var pathFigure = new PathFigure(start, list, false);
var pfList = new List<PathFigure>(1);
pfList.Add(pathFigure);
group.Children.Add(new PathGeometry(pfList));
}
這裏產生的幾何始終有一個透明筆觸,但可以使用填充屬性使弧可見。
下面是我用來創建半圓的長方形當量的代碼:
public void AddPath(IList<ModelPoint2D> Points, LineVisualStyle lineStyle)
{
List<LineSegment> list = new List<LineSegment>(Points.Count);
Point start = converter.ToPoint2D(Points[0]);
for (int i = 1; i < Points.Count; i++)
{
list.Add(new LineSegment(converter.ToPoint2D(Points[i]), true));
}
var pathFigure = new PathFigure(start, list, false);
var pfList = new List<PathFigure>(1);
pfList.Add(pathFigure);
group.Children.Add(new PathGeometry(pfList));
}
使用線段的代碼產生,響應兩個筆觸和填充設置的幾何形狀。
所得呈現如下:
The Semicircle at the top has Fill visible but not Stroke
我已經嘗試了許多組合,包括直接添加的PathGeometry到Path.Data而不是裹在GeometryGroup。
任何建議/援助將不勝感激。
請求VisualModel代碼如下:
public abstract class VisualModel
{
/// <summary>
/// Recursive hierarchy of VisualModel objects that describe the visual structure of an entity for a specific ViewportType.
/// The top level of the hierarchy is owned by EntityViews via a ViewportTypeVisualModel entry
/// </summary>
/// <param name="id">An optional model component identifier - useful for debug</param>
public VisualModel(string id)
{
domainBindings = null;
proxies = null;
Id = id;
ParentVisualModel = null;
LocalTransforms = null;
IsStatic = true;
}
public bool HasDomainBindings
{
get
{
if (domainBindings == null)
return false;
return domainBindings.Count > 0;
}
}
public bool HasProxies
{
get
{
if (proxies == null)
return false;
return proxies.Count > 0;
}
}
public string Id { get; private set; }
/// <summary>
/// Static objects are not affected by transforms that change after the render is constructed.
/// Non-Static (Dynamic) objects have transforms that may be changed by the application after the render is constructed
/// Dynamic objects have attached event handlers that adjust the transforms in response to application events
/// </summary>
public bool IsStatic { get; private set; }
public List<TransformBase> LocalTransforms { get; private set; }
public VisualModel ParentVisualModel { get; internal set; }
public void AddDomainBinding(BindingBase binding)
{
DomainBindings.Add(binding);
}
public void AddLocalTransform(TransformBase transform)
{
if (LocalTransforms == null)
LocalTransforms = new List<TransformBase>(4);
LocalTransforms.Add(transform);
if (transform.IsDynamic)
IsStatic = false;
}
public void AddProxy(VisualProxy visualProxy)
{
Proxies.Add(visualProxy);
}
protected List<BindingBase> DomainBindings
{
get
{
if (domainBindings == null)
domainBindings = new List<BindingBase>();
return domainBindings;
}
}
protected List<VisualProxy> Proxies
{
get
{
if (proxies == null)
proxies = new List<VisualProxy>();
return proxies;
}
}
public virtual void UnbindAll()
{
if (domainBindings == null)
return;
foreach (BindingBase binding in this.DomainBindings)
binding.UnBind();
}
private List<BindingBase> domainBindings;
private List<VisualProxy> proxies;
}
注意VisualModel表示圖形/渲染技術無關模型容器。它包含的VisualProxy對象是特定於技術的圖形對象的基類。在這種情況下,WpfVisual2DProxy對象包裝包含我的WPF可呈現表示的WPF UIElement對象。
以下是VisualProxy:
public abstract class VisualProxy
{
public VisualModel.VisualModel VisualModel { get; private set; }
public VisualProxy Parent { get; private set; }
public VisualProxy(VisualModel.VisualModel visualModel)
{
VisualModel = visualModel;
Parent = null;
}
public VisualProxy(VisualModel.VisualModel visualModel, VisualProxy parent)
{
VisualModel = visualModel;
Parent = parent;
}
}
而且下面是WpfVisual2DProxy:
public class WpfVisual2DProxy : VisualProxy
{
public UIElement Visual2D { get; private set; }
public WpfVisual2DProxy(UIElement visual2D, VisualModel visualModel) : base(visualModel)
{
Visual2D = visual2D;
}
public WpfVisual2DProxy(UIElement visual2D, VisualModel visualModel, WpfVisual2DProxy parent) : base(visualModel, parent)
{
Visual2D = visual2D;
}
}
是否'ArcSegment'顯示青色當您使用'visual2D.Stroke = Brushes.Cyan;''而不是= visual2D.Stroke((PathElement)visualModel).LineStyle.LineBrush的;'?如果不是,你可以發佈代碼來顯示'visualModel'是如何構建的? – Peter
我試過直接分配visual2D.Stroke = Brushes.Black;這沒有什麼區別。我在原始文章中添加了一些額外的細節,以顯示正在使用的各種模型容器對象。 –
最後的ArcSegment構造函數參數isStroked顯然應該設置爲true而不是false。 – Clemens