Не работает система Datagrid - ObservableCollection - Polygon

104
03 декабря 2020, 04:50

Я работаю над автоматизированным местом Диспетчера, у которого должна быть активная карта. Карту я реализую в WPF с использованием шаблона MVVM. И в процессе разработки возникла следующая проблема: При редактировании точек объекта, значение точек меняется а обновление созданных объектов типа Polygon не происходит, и объект остается таким как создавался. Поворот объектов и перемещение относительно 0 работает. Код представлен ниже. Модель. Реализует интерфейс INotifyPropertyChanged и включает в себя: Имя объекта, коллекцию точек для построения объекта, угол поворота объекта, координаты объекта для смещения и класса Point с реализацией INotifyPropertyChanged.

class Poligon : INotifyPropertyChanged
{
    public class Point : INotifyPropertyChanged
    {
        public Point(double valueX, double valueY)
        {
            x = valueX;
            y = valueY;
        }
        private double x;
        public double X
        {
            get { return x; }
            set
            {
                x = value;
                OnPropertyChanged("X");
            }
        }
        private double y;
        public double Y
        {
            get { return y; }
            set
            {
                y = value;
                OnPropertyChanged("Y");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName]string prop = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    }
    public ObservableCollection<Point> Points { get; set; }

    private string name;
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            OnPropertyChanged("Name");
        }
    }
    private float angleOfRotation;
    public float AngleOfRotation
    {
        get { return angleOfRotation; }
        set
        {
            angleOfRotation = value;
            OnPropertyChanged("AngleOfRotation");
        }
    }
    private double biasX;
    public double BiasX
    {
        get { return biasX; }
        set
        {
            biasX = value;
            OnPropertyChanged("BiasX");
        }
    }
    private double biasY;
    public double BiasY
    {
        get { return biasY; }
        set
        {
            biasY = value;
            OnPropertyChanged("BiasY");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName]string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

Представление. Также реализует интерфейс INotifyPropertyChanged и включает в себя: конструктор, коллекцию объектов типа Poligon, и объект для выбора нужного полигона.

введите сюда кодclass ViewPoligon : INotifyPropertyChanged
{
    public ObservableCollection<Poligon> Poligons { get; set; }
    public ViewPoligon()
    {
        Poligons = new ObservableCollection<Poligon>
        {
            new Poligon
            {
                Name = "Полигон 1",
                AngleOfRotation = 45,
                Points = new ObservableCollection<Poligon.Point>
                {
                    new Poligon.Point(0, 0),
                    new Poligon.Point(0, 50),
                    new Poligon.Point(50, 50),
                    new Poligon.Point(50, 0)
                },
                BiasX = 30,
                BiasY = 30
            },
            new Poligon
            {
                Name = "Полигон 2",
                AngleOfRotation = 45,
                Points = new ObservableCollection<Poligon.Point>
                {
                    new Poligon.Point(0, 0),
                    new Poligon.Point(0, 75),
                    new Poligon.Point(75, 75),
                    new Poligon.Point(75, 0)
                },
                BiasX = 75,
                BiasY = 75
            }
        };
    }
    private Poligon selectedItem;
    public Poligon SelectedItem
    {
        get
        {
            return selectedItem;
        }
        set
        {
            selectedItem = value;
            OnPropertyChanged("SelectedItem");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName]string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

Представление модели. Рабочая область разделена на 2 области. в первой выводиться информация об объектах, где и производиться их редактирование, во второй области на объекте компоновки Canvas строятся объекты типа Polygons. Данный тип объектов принимает в качестве коллекции точек PointCollection, а от объекта мы передаем ObservableCollection. Данную проблему я решал с помощь конвертора.

    <Window.Resources>
    <local:PointConverter x:Key="myConverter"/>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <StackPanel>
        <TextBlock Text="Объекты:"></TextBlock>
        <ListBox Margin="10,5,10,5" ItemsSource="{Binding Poligons}" SelectedItem="{Binding SelectedItem}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"></TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <StackPanel Margin="10,5,10,5" DataContext="{Binding SelectedItem}">
            <TextBlock Text="Угол поворота:"></TextBlock>
            <TextBox Text="{Binding AngleOfRotation}"/>
            <TextBlock Text="Смещение:"></TextBlock>
            <StackPanel Orientation="Horizontal">
                <TextBox Margin="5" Width="80" Text="{Binding BiasX}"></TextBox>
                <TextBox Margin="5" Width="80" Text="{Binding BiasY}"></TextBox>
            </StackPanel>
            <DataGrid ItemsSource="{Binding Points}"></DataGrid>
        </StackPanel>
    </StackPanel>
    <ItemsControl ItemsSource="{Binding Poligons}" Grid.Column="1">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas></Canvas>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Polygon Points="{Binding Points, Converter={StaticResource myConverter}}" Fill="#FFE21414" RenderTransformOrigin="0,0" FillRule="Nonzero">
                    <Polygon.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform/>
                            <SkewTransform/>
                            <RotateTransform Angle="{Binding AngleOfRotation}"/>
                            <TranslateTransform X="{Binding BiasX}" Y="{Binding BiasY}"/>
                        </TransformGroup>
                    </Polygon.RenderTransform>
                </Polygon>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Конвертор. Преобразует ObservableCollection в PointCollection.

class PointConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        PointCollection temp = new PointCollection();
        if (value != null)
        {
            foreach (var item in (ObservableCollection<Poligon.Point>)value)
                temp.Add(new Point(item.X, item.Y));
        }
        return temp;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ObservableCollection<Poligon.Point> temp = new ObservableCollection<Poligon.Point>();
        if (value != null)
        {
            foreach (var item in (PointCollection)value)
                temp.Add(new Poligon.Point(item.X, item.Y));
        }
        return temp;
    }
}

MainWindow

    public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewPoligon();
    }
}
READ ALSO
Парсинг CSR библиотекой bouncy castle в С#

Парсинг CSR библиотекой bouncy castle в С#

Есть необходимость проверять запросы на сертификаты(CSR)Сам запрос раскладываю так:

89
Запуск jar с помощью C#

Запуск jar с помощью C#

Всем доброго времени сутокДолго ломаю голову (я в шарпах не спец), почему это не работает

103
Как изменить цвет фрейма?

Как изменить цвет фрейма?

Хочу изменить цвет фрейма/рамки у формыБольшая кастомизация не требуется и убирать рамку и делать свою тоже не нужно

134
Кастомный UI для видеоплеера(MpvPlayerUI.NET) на WPF

Кастомный UI для видеоплеера(MpvPlayerUI.NET) на WPF

В общем на GitGub нашел библиотеку MpvPlayerUINET https://github

101