1

我正在尝试将 Data 字段绑定到 WPF 路径对象上。我尝试了两种不同的方法,但两种方法都不会触发更新的绘图。

计划一:

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

SegmentPoints 是一个ObservableCollection<Point>. 转换器返回一个新的 StreamGeometry 对象。我预计如果我替换了集合中的一个点,这个东西会重新绘制。那是行不通的。如果我触发 SegmentPoints 的 PropertyChanged 事件,它会重绘。

计划二:

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

然后,在视图模型中,我更新了我的BezierSegment.Point3. 因为各种段类型上的 Point 属性是 DependencyProperties,所以我认为我可以更新它们,它们会触发并更改树。显然也不是这样。

所以我的问题是:有什么方法可以手动触发 Path 对象的更新?(如果是这样,我可能会使用 NotifyOnTargetUpdated。)是否有某种方法可以配置系统,以便段上的点更改将触发重绘?

4

1 回答 1

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属性,而是直接在 XAML 或代码中分配 PathFigureCollection。

<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 类定义了一个Figures属性,该属性分配给FiguresPathGeometry 的属性。

<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
    });
于 2013-04-29T21:50:50.707 回答