0

内部にクラス(それを呼びましょうexternalClass)があります。ObservableCollection<Point> channel1(クラス自体はINotifyを実装していません)

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プロパティとして公開してみてINotifyPropertyChanged"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 に答える