0

我有一个有内部的类(我们称之为externalClassObservableCollection<Point> channel1。(类本身不实现 INotify)

在 MainWindow 中,我有一条折线绑定到它externalClass.channel1,它使用从 ObservableCollection 到 PointCollection 的转换器。

因此,从我绑定的 C#DataContext = externalClass; 和 XAML 中的折线看起来像:

<Polyline Points="{Binding channel1, Converter={StaticResource pointCollectionConverter}}" Stroke="#FF00E100" Name="line" />

我有一个像这样工作的测试功能:

public void test()
{
   ObservableCollection<Point> newone = new ObservableCollection<Point>();
   for (int i = 0; i < debugCh1.Count; i++)
   {
      Point p1 = debugCh1[i];
      p1.Y = p1.Y + 1;
      newone.Add(p1);
   }
   channel1= newone;
}

如果我在转换器本身中添加一个断点,我可以看到它在启动时被调用(并且实际上显示了初始值(硬编码)。但是当我将测试功能添加到按钮时......它什么也不做(转换器没有被调用)

关于更改通知在哪里停止的任何想法???

解决方案

在阅读了答案并在谷歌上搜索了一下之后,我有了灵魂。我想把它贴在那里给其他人

所以 .. 所谓的 externalClass 必须继承自 INotifyPropertyChanged 并且必须实现 NotifyPropertyChanged 所以所有的一切都必须这样声明:

public class externalClass  : INotifyPropertyChanged
{ 
  ....
    // at some point you have your ObservableCollection<smth> as a property 
    public ObservableCollection<Point> channel1 { get; set; }
  ....
    //at some point you implement NotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string caller)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(caller));
        }
    }
   ....
   //then whenever you need to fire the notification
   [..]do something with channel1
   NotifyPropertyChanged("channel1");

就这样。如果你添加一个适当的绑定(就像我在我的问题中展示的那样),整个设置都会起作用..至少我的工作有效,呵呵

祝你好运!并感谢帮助我的人!:D

4

2 回答 2

1

INotifyCollectionChanged折线点可能在绑定时不听。尝试暴露Channel1为属性并提高INotifyPropertyChangedwith"Channel1"

于 2012-12-03T07:41:12.307 回答
0

首先,您需要创建自定义类PointCollection

public class PointCollection : ObservableCollection<Point>
{
    public PointCollection()
    {

    }


    public PointCollection(IEnumerable<Point> points) : base(points)
    {

    }
}

其次,您需要创建自定义Polyline

public class PolylineDynamic : Shape
{
    private Geometry _polylineGeometry = Geometry.Empty;

    public static readonly DependencyProperty PointsProperty = DependencyProperty.Register(nameof(Points), typeof(PointCollection), typeof(PolylineDynamic), new FrameworkPropertyMetadata(PointsChanged));

    private static void PointsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((PolylineDynamic)d).PointsChanged(e);
    }

    private void PointsChanged(DependencyPropertyChangedEventArgs e)
    {
        if (e.OldValue is PointCollection oldPoints)
            oldPoints.CollectionChanged -= OnPointsChanged;
        if (e.NewValue is PointCollection newPoints)
            newPoints.CollectionChanged += OnPointsChanged;
        UpdatePolyline();
    }

    public PointCollection Points
    {
        get => (PointCollection)GetValue(PointsProperty);
        set => SetValue(PointsProperty, value);
    }

    public static readonly DependencyProperty FillRuleProperty = DependencyProperty.Register(nameof(FillRule), typeof(FillRule), typeof(PolylineDynamic), new FrameworkPropertyMetadata(FillRule.EvenOdd));

    public FillRule FillRule
    {
        get => (FillRule)GetValue(FillRuleProperty);
        set => SetValue(FillRuleProperty, value);
    }

    protected override Geometry DefiningGeometry => _polylineGeometry;

    private void OnPointsChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                var aPoint = e.NewItems.OfType<Point>().Single();
                Add(aPoint, e.NewStartingIndex);
                break;
            case NotifyCollectionChangedAction.Remove:
                Remove(e.OldStartingIndex);
                break;
            case NotifyCollectionChangedAction.Replace:
                var rPoint = e.NewItems.OfType<Point>().Single();
                Replace(rPoint, e.NewStartingIndex);
                break;
        }
    }

    protected void UpdatePolyline()
    {
        if (Points == null || Points.Count < 2)
            _polylineGeometry = Geometry.Empty;
        else
        {
            var pGeometry = GetPathGeometry();
            for (var i = 0; i < Points.Count; i++)
            {
                if (i == 0)
                    continue;
                var startPoint = Points[i - 1];
                var point = Points[i];
                var figure = new PathFigure { StartPoint = startPoint };
                figure.Segments.Add(new LineSegment(point, true));
                pGeometry.Figures.Add(figure);
            }
        }
    }

    private void Add(Point point, int index)
    {
        var pGeometry = GetPathGeometry();
        if (pGeometry.Figures.Count == 0)
        {
            UpdatePolyline();
            return;
        }

        if (index == Points.Count - 1)
        {
            var segment = new LineSegment(point, true);
            var figure = new PathFigure { StartPoint = Points[index - 1] };
            figure.Segments.Add(segment);
            pGeometry.Figures.Add(figure);
        }
        else if (index == 0)
        {
            var segment = new LineSegment(Points[1], true);
            var figure = new PathFigure { StartPoint = point };
            figure.Segments.Add(segment);
            pGeometry.Figures.Insert(0, figure);
        }
        else
        {
            var leftFigure = new PathFigure { StartPoint = Points[index - 1] };
            leftFigure.Segments.Add(new LineSegment(point, true));
            var rightFigure = new PathFigure { StartPoint = point };
            rightFigure.Segments.Add(new LineSegment(Points[index + 1], true));
            pGeometry.Figures.Insert(index - 1, leftFigure);
            pGeometry.Figures.Insert(index, rightFigure);
        }
        InvalidateVisual();
    }

    private void Remove(int index)
    {
        var pGeometry = GetPathGeometry();
        if (!pGeometry.Figures.Any())
        {
            _polylineGeometry = Geometry.Empty;
            InvalidateVisual();
            return;
        }

        if (index == Points.Count - 1 || index == 0)
            pGeometry.Figures.RemoveAt(index);
        else
        {
            var leftFigure = pGeometry.Figures[index - 1];
            var rightFigure = pGeometry.Figures[index];
            pGeometry.Figures.RemoveAt(index - 1);
            rightFigure.StartPoint = ((LineSegment)leftFigure.Segments.Single()).Point;
        }
        InvalidateVisual();
    }

    private void Replace(Point point, int index)
    {
        var pGeometry = GetPathGeometry();
        if (index == 0)
            pGeometry.Figures[0].StartPoint = point;
        else if (index == Points.Count - 1)
            ReplaceSegment(pGeometry.Figures[index - 1], point);
        else
        {
            ReplaceSegment(pGeometry.Figures[index - 1], point);
            pGeometry.Figures[index].StartPoint = point;
        }
        InvalidateVisual();
    }

    private void ReplaceSegment(PathFigure figure, Point point)
    {
        figure.Segments.Clear();
        figure.Segments.Add(new LineSegment(point, true));
    }

    private PathGeometry GetPathGeometry()
    {
        if (_polylineGeometry is PathGeometry pathGeometry)
            return pathGeometry;
        else
        {
            pathGeometry = new PathGeometry { FillRule = FillRule };
            _polylineGeometry = pathGeometry;
            return pathGeometry;
        }
    }
}

如果您需要更多功能,可以添加更多)

于 2018-05-25T12:31:44.583 回答