2013-04-29 59 views
1

我試圖綁定WPF路徑對象上的數據字段。我嘗試了兩種不同的方法,但都沒有辦法觸發更新的圖紙。WPF路徑形狀數據綁定:她不更新

計劃1:

<Path Data="{Binding SegmentPoints, Converter={StaticResource PointsToBezier}}" ... /> 

SegmentPoints是ObservableCollection<Point>。轉換器返回一個新的StreamGeometry對象。我預計如果我在集合中替換了一個點,那麼這個東西就會重繪。這是行不通的。如果我觸發SegmentPoints的PropertyChanged事件,它會重繪。

計劃2:

<Path ...><Path.Data><PathGeometry Figures="{Binding Figures}" .../>... 

然後,視圖模型裏面,我更新的東西像我BezierSegment.Point3。因爲各種細分類型的Point屬性都是DependencyProperties,所以我認爲我可以更新,然後觸發並更改樹。這顯然不是這種情況。

所以我的問題: 有沒有辦法來手動觸發一個路徑對象的更新? (如果是這樣,我可能會使用NotifyOnTargetUpdated。)有沒有一種方法來配置系統,使得段上的點改變會觸發重繪?

回答

1

只有當SegmentPoint屬性發生更改時(即分配給新集合),纔會更新第一種方法中的綁定。因此它不需要是ObservableCollection。只需創建一個新的收藏集並提高PropertyChanged事件。

public class ViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private ICollection<Point> segmentPoints; 

    public ICollection<Point> SegmentPoints 
    { 
     get { return segmentPoints; } 
     set 
     { 
      segmentPoints = value; 

      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("SegmentPoints")); 
      } 
     } 
    } 
} 

然而,在你的第二個辦法,關鍵是不給的PathGeometry的Figure屬性綁定,而是直接分配PathFigureCollection,無論是在XAML或代碼。

<Canvas Background="Transparent" MouseMove="Canvas_MouseMove"> 
    <Path Stroke="Blue" StrokeThickness="3"> 
     <Path.Data> 
      <PathGeometry> 
       <PathGeometry.Figures> 
        <PathFigureCollection x:Name="figures"/> 
       </PathGeometry.Figures> 
      </PathGeometry> 
     </Path.Data> 
    </Path> 
</Canvas> 

中的代碼添加段和修改其屬性:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     var segment = new BezierSegment(new Point(100, 0), new Point(200, 300), new Point(300, 100), true); 
     var figure = new PathFigure(); 
     figure.Segments.Add(segment); 
     figures.Add(figure); 
    } 

    private void Canvas_MouseMove(object sender, MouseEventArgs e) 
    { 
     var firstSegment = figures[0].Segments[0] as BezierSegment; 
     firstSegment.Point2 = e.GetPosition(sender as IInputElement); 
    } 
} 

您也可以在代碼中創建Figures屬性,如下圖所示。 MainWindow類定義分配給PathGeometry的Figures屬性的Figures屬性。

<Canvas Background="Transparent" MouseMove="Canvas_MouseMove"> 
    <Path Stroke="Blue" StrokeThickness="3"> 
     <Path.Data> 
      <PathGeometry x:Name="geometry"/> 
     </Path.Data> 
    </Path> 
</Canvas> 

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     var segment = new BezierSegment(new Point(100, 0), new Point(200, 300), new Point(300, 100), true); 
     var figure = new PathFigure(); 
     figure.Segments.Add(segment); 

     Figures = new PathFigureCollection(); 
     Figures.Add(figure); 

     geometry.Figures = Figures; 
    } 

    public PathFigureCollection Figures { get; set; } 

    private void Canvas_MouseMove(object sender, MouseEventArgs e) 
    { 
     var firstSegment = Figures[0].Segments[0] as BezierSegment; 
     firstSegment.Point2 = e.GetPosition(sender as IInputElement); 
    } 
} 

顯然,更新的路徑數據將不會在綁定的Figures物業工作。以下綁定只分配一次數字,但稍後的更改不會反映在路徑中。

// replace 
// geometry.Figures = Figures; 
// by 
BindingOperations.SetBinding(geometry, PathGeometry.FiguresProperty, 
    new Binding 
    { 
     Path = new PropertyPath("Figures"), 
     Source = this 
    }); 
+0

儘管如此,對於「是否有某種方法可以手動觸發路徑對象的更新?」並不完全是答案。 – Clemens 2013-04-29 22:03:42

+0

我有一個2000段的列表。我不太喜歡重新創建2000個細分的想法,而有人在屏幕上拖動一個點。 – Brannon 2013-04-29 22:03:46

+0

您是否遇到任何性能問題? – Clemens 2013-04-29 22:04:25