PointCollection ItemSource 바인딩 오류 문의

안녕하세요.

WPF가 아직 초보라서… 하루종일 여기에서 살고 있습니다.

항상 감사드립니다.

제가 문의드리고자하는 것은

  1. Lines라는 PointCollection 프로퍼티를 ItemsSource로 받고 있을때, Item에 해당하는 항목에 Binding 될 때 오류가 나타납니다.(바인딩 에러)

오류는 아래와 같이 나옵니다.(바인딩 에러 항목도 나오고요)
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:(no path); DataItem=null; target element is ‘EllipseGeometry’ (HashCode=14867369); target property is ‘Center’ (type ‘Point’) …이하 중략

LinePointsViewModel.cs

namespace Canvas.Add.Lines.ViewModels
{
    public class LinePointsViewModel
        :Screen
    {
        public LinePointsViewModel()
        {
            _linePoints = new PointCollection();
            //_linePoints.Changed += CollectionChanged;
        }

        private void CollectionChanged(object sender, EventArgs e)
        {
//내부적으로 포인트 추가 삭제, 변경이 있을 떄 PropertyChange하는 로직이 
//있으면 좋겠는데... 
        }

        private PointCollection _linePoints;

        public PointCollection LinePoints
        {
            get { return _linePoints; }
            set 
            { 
                _linePoints = value;
                NotifyOfPropertyChange(() => LinePoints);
            }
        }

    }
}

LineViewModel.cs

namespace Canvas.Add.Lines.ViewModels
{
    public class LineViewModel
        :Screen
    {
        public LineViewModel()
        {
            //var pClass = IoC.Get<LinePointsViewModel>();
            //Lines = new ObservableCollection<LinePointsViewModel>();
            Lines = new TrulyObservableCollection<LinePointsViewModel>();
        }

        private TrulyObservableCollection<LinePointsViewModel> _lines;

        public TrulyObservableCollection<LinePointsViewModel> Lines
        {
            get { return _lines; }
            set 
            {
                _lines = value;
                NotifyOfPropertyChange(() => Lines);
            }
        }

    }
}

LineView.xaml

<UserControl x:Class="Canvas.Add.Lines.Views.LineView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Canvas.Add.Lines.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    
    <ItemsControl ItemsSource="{Binding Lines, UpdateSourceTrigger=PropertyChanged}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Canvas>
                    <Polyline Points="{Binding LinePoints, UpdateSourceTrigger=PropertyChanged}"
                              StrokeThickness="2.0"
                              Stroke="Black" />

                    <ItemsControl ItemsSource="{Binding LinePoints,  UpdateSourceTrigger=PropertyChanged}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <Canvas />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>

                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Path StrokeThickness="1.0"
                                      Stroke="Black"
                                      Fill="MistyRose">
                                    <Path.Data>
                                         <EllipseGeometry Center="{Binding }"
                                                         RadiusX="4"
                                                         RadiusY="4" />
                                    </Path.Data>
                                </Path>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </Canvas>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</UserControl>

해결책을 찾을 수 있을까요?

3개의 좋아요

위 오류는 LinePoints객체를 바인딩 했을시 아마도 하위 비주얼 요소의 DataType은
IEnumerable <Point>로 처리 되서
EllipseGeometry의 Center속성인 Point구조체 타입으로 변경할 수 없기 때문에 바인딩 오류가 나는 것 입니다.

이를 해결하려면 명시적으로 Point타입으로 바인딩 처리를 해주시면 됩니다.

간단하게는 컨버터를 이용하는 방법이 있습니다.

public class EllipseGeometryCenterConverter : IValueConverter
{
    public object Convert(object value, Type targetType,  etc parameter ........)
    {
        // PointCollection 인덱서로 Converter가 호출되면서 value가 Point 구조체로 평가되기때문에 바로 return으로 사용
        return value;
    }

    ... 기타 생략...
}

그런데 추측컨데… 바인딩 오류가 출력되긴 하지만
wpf 바인딩 엔진이 자동으로 처리해서 아마 정상적으로 표시되지 않던가요??

추가적으로 올려주신 코드의 주석 내용중

이 부분은 LineView 뷰에 사용되는 뷰모델인 LineViewModel에서
ObservableCollection의 CollectionChanged 이벤트로 처리하면 될 것 같습니다.

5개의 좋아요

답변 감사드립니다.

네 바인딩 오류는 나지만 시현은 정상적으로 되요.

CollectionPropertyChange 이벤트 걸어서 해보겠습니다.

감사합니다.

1개의 좋아요