Page 1 of 1

Unable to set binding with PolyLineSegment.Points property

Posted: 11 Nov 2022, 15:07
by daniilch
Hello. I'm trying to implement sort of a painting utility, which allows a user to draw continuous line with mouse. To implement that I'm creating a viewmodel with `ICollection<Noesis.Point> Points` property and bind it in xaml in following way:
<DataTemplate DataType="{x:Type vm:PolyLineViewModel}">
    <Path
        StrokeEndLineCap="Round"
        StrokeLineJoin="Round"
        StrokeStartLineCap="Round"
        StrokeThickness="{Binding LineThickness}">
        <Path.Stroke>
            <SolidColorBrush Color="{Binding Color}" />
        </Path.Stroke>
        <Path.Data>
            <PathGeometry>
                <PathFigure x:Name="clipFigure" IsClosed="{Binding IsClosed}">
                    <PathFigure.Segments>
                        <PolyLineSegment Points="{Binding Points}" />
                    </PathFigure.Segments>
                </PathFigure>
            </PathGeometry>
        </Path.Data>
    </Path>
</DataTemplate>
However, I can't get it to work, and all I get is an error in log:
 [NOESIS/E] Binding failed: Path=Points, Source=Brio.MRS.PhotoEditor.ViewModels.PolyLineViewModel(''), Target=PolyLineSegment(''), TargetProperty=PolyLineSegment.Points
Other properties in my view are bound correctly, so it's not a simple DataContext or binding path issue. I found an existing bug in bugtracker (https://www.noesisengine.com/bugs/view.php?id=2308) about the same exact issue, but it's marked as solved in version 3.1.4, and it's indeed the version I'm using. Any help is appreciated.

Re: Unable to set binding with PolyLineSegment.Points property

Posted: 11 Nov 2022, 15:16
by daniilch
Addendum: by the way, I think there's a mistake somewhere in your SWIG configuration for PolyLineSegment class, because it generates a constructor with the following signature:
public PolyLineSegment(ref Point points, uint numPoints, bool isStroked)
which (I guess) is generated from C++ class receiving Point array pointer. WPF equivalent has the following signature:
public PolyLineSegment(IEnumerable<Point> points, bool isStroked)

Re: Unable to set binding with PolyLineSegment.Points property

Posted: 11 Nov 2022, 19:05
by sfernandez
Yes, in 3.1.4 we fixed issue #2308, and I just tested it and if I create a VM exposing a PointCollection it works as expected:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VM
{
    public Noesis.PointCollection Points { get; } = new Noesis.PointCollection();
}

public class PointCollectionBehavior : MonoBehaviour
{
    void Start()
    {
        VM vm = new VM();
        vm.Points.Add(new Noesis.Point(200, 100));
        vm.Points.Add(new Noesis.Point(150, 200));
        vm.Points.Add(new Noesis.Point(200, 300));
        vm.Points.Add(new Noesis.Point(0, 200));

        NoesisView view = GetComponent<NoesisView>();
        view.Content.DataContext = vm;
    }
}
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <Path Stroke="Black">
      <Path.Data>
        <PathGeometry>
          <PathFigure StartPoint="100,100" IsClosed="True">
            <PolyLineSegment Points="{Binding Points}"/>
          </PathFigure>
        </PathGeometry>
      </Path.Data>
    </Path>
  </StackPanel>
</Grid>
Does that work for you?
Addendum: by the way, I think there's a mistake somewhere in your SWIG configuration for PolyLineSegment class, because it generates a constructor with the following signature:
You are right, this code was incorrectly auto-generated by SWIG. Could you please create a ticket about it in our bugtracker?
Thanks a lot for reporting it.

Re: Unable to set binding with PolyLineSegment.Points property

Posted: 14 Nov 2022, 07:37
by daniilch
Yes, your code sample does work correctly. However, you use binding to PointCollection in your viewModel. I guess, collection binding should work with any collection type? Changing you sample code to the following one leads to binding fail:
public class VM
{
    public List<Noesis.Point> Points { get; } = new List<Noesis.Point>();
}
You are right, this code was incorrectly auto-generated by SWIG. Could you please create a ticket about it in our bugtracker?
Sure, here it is: https://www.noesisengine.com/bugs/view.php?id=2459

Re: Unable to set binding with PolyLineSegment.Points property

Posted: 15 Nov 2022, 10:15
by sfernandez
Thanks for the report.

Regarding the Points property, WPF doesn't work either if you try to bind a List<Point> collection:
Cannot convert from type 'System.Collections.Generic.List`1[System.Windows.Point]' to 'System.Windows.Media.PointCollection'. Consider setting a converter on the binding.

Re: Unable to set binding with PolyLineSegment.Points property

Posted: 15 Nov 2022, 16:24
by daniilch
Oh, you are right. Sorry, I was so sure that the Binding should work with any collection type, that didn't check it in WPF. Shame on me. Thanks for your time.

Re: Unable to set binding with PolyLineSegment.Points property

Posted: 16 Nov 2022, 16:58
by sfernandez
Not a problem, glad to be helpful!