2017-10-15 99 views
0

我正在嘗試使用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; 
    } 
} 
+0

是否'ArcSegment'顯示青色當您使用'visual2D.Stroke = Brushes.Cyan;''而不是= visual2D.Stroke((PathElement)visualModel).LineStyle.LineBrush的;'?如果不是,你可以發佈代碼來顯示'visualModel'是如何構建的? – Peter

+0

我試過直接分配visual2D.Stroke = Brushes.Black;這沒有什麼區別。我在原始文章中添加了一些額外的細節,以顯示正在使用的各種模型容器對象。 –

+2

最後的ArcSegment構造函數參數isStroked顯然應該設置爲true而不是false。 – Clemens

回答

0

非常感謝大家誰把他們的頭腦,以我的問題。

克萊門斯是正確的。我的ArcSegment沒有將isStroked設置爲true。

尷尬簡單。

謝謝