Как распределить шаблонные элементы из 2 списков на Canvas на основе свойств привязки к X и Y позиции в WPF с использованием MVVM - PullRequest
0 голосов
/ 13 февраля 2019

Мне нужно рисовать шаблонные элементы из 2 списков на холсте в соответствии со свойствами положения X и Y.Проблема заключается в том, что элементы не отображаются в соответствующих координатах, они находятся в [0,0] координатах.

У меня есть представление MainWindow.xaml и соответствующий файл .cs.Я сделал новую ViewModel, где у меня есть ObservableCollection рельсов.Каждый рельс имеет свой список вершин и список ребер.Эти списки заполнены множеством вершин и ребер.В настоящее время коллекция рельсов имеет только один рельс (изменится в будущем).

В MainWindow.xaml я создал 2 DataTemplates, один для вершины и один для ребра, и создал селектор, которыйвозвращает другой шаблон на основе последнего возвращенного шаблона.Эта часть работает нормально.

Вот MainWindow.xaml ( MainWindow.xaml.cs имеет одно основное функциональное событие кнопки, остальное не изменяется (со времени созданияфайл)):

<Window.Resources>
        <ViewModels:TratViewModel x:Key="Trat"></ViewModels:TratViewModel>
        <Converters:SwitchListConverter x:Key="BodUsekSwitcher"></Converters:SwitchListConverter>
        <Template:TratItemTemplateSelector x:Key="TratItemSelector"></Template:TratItemTemplateSelector>
</Window.Resources>

У меня также есть DataTemplate-s для вершин и ребер в Window.Resources, но, поскольку они верны и этот вопрос будет длинным, я их опускаю.Остальная часть MainWindow.xaml:

<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" Height="150">
                <TabControl DataContext="{StaticResource Trat}" ItemsSource="{Binding ZoznamTrati}">

                    <TabControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="My rail"></TextBlock>
                        </DataTemplate>
                    </TabControl.ItemTemplate>

                    <TabControl.ContentTemplate>
                        <DataTemplate>
                            <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Hidden">
                                <Canvas Width="760" Height="100" Background="DodgerBlue">

                                    <ItemsControl ItemTemplateSelector="{StaticResource TratItemSelector}">
                                        <ItemsControl.ItemsSource>
                                            <MultiBinding Converter="{StaticResource BodUsekSwitcher}">
                                                <Binding Path="BodList" />
                                                <Binding Path="UsekList" />
                                            </MultiBinding>
                                        </ItemsControl.ItemsSource>

                                        <ItemsControl.ItemsPanel>
                                            <ItemsPanelTemplate>
                                                <Canvas/>
                                            </ItemsPanelTemplate>
                                        </ItemsControl.ItemsPanel>

                                        <!-- Maybe error here? -->
                                        <ItemsControl.ItemContainerStyle>
                                            <Style TargetType="ContentPresenter">
                                                <Setter Property="Canvas.Left" Value="{Binding AktualneX}"/>
                                                <Setter Property="Canvas.Top" Value="{Binding AktualneY}"/>
                                            </Style>
                                        </ItemsControl.ItemContainerStyle>

                                    </ItemsControl>
                                </Canvas>
                            </ScrollViewer>
                        </DataTemplate>
                    </TabControl.ContentTemplate>
                </TabControl>
            </StackPanel>

Как вы можете видеть, я вставил в TabControl, установил DataContext для моей ViewModel (там есть мой список рельсов, с только одна рельс на данный момент) и установите ItemsSource в список рельсов.Вкладка заголовка показывает название рельса («Мой рельс»).Элементы вкладки - ScrollViewers с Canvas.Canvas имеет ItemsControl, который выбирает либо из списка вершин ( BodList ), либо из списка ребер ( UsekList ) (выбор осуществляется с помощью переключателя, код приведен ниже).Эти списки в моем рельсе (gptrat, можно найти в коде TratViewModel ниже).Существует также Выбор шаблона, который выбирает соответствующий шаблон в зависимости от типа элемента (вершина / ребро).Этот селектор работает отлично.

Вот TratViewModel :

namespace Editor.ViewModels
{
    public class TratViewModel
    {
        private int _y;
        private int _x;
        public int AktualneY
        {
            get
            {
                return _y;
            }

            set
            {
                _y = value;
            }
        }

        public int AktualneX
        {
            get
            {
                return _x;
            }

            set
            {
                _x = value;
            }
        }

        // List of Rails
        private ObservableCollection<GP_Trat> _zoznamTrati;
        public ObservableCollection<GP_Trat> ZoznamTrati
        {
            get
            {
                return _zoznamTrati;
            }

            set
            {
                if (_zoznamTrati != value)
                {
                    _zoznamTrati = value;
                    // NotifyPropertyChanged
                }
            }
        }

        public TratViewModel() {
            // List of Rails
            ZoznamTrati = new ObservableCollection<GP_Trat>();

            // The one rail i read from XML file, works OK
            // It contains List of Vertices and List of Edges, also OK
            GP_Trat gptrat = GPIO.ReadGPTrat("PathToXMLFile");
            ZoznamTrati.Add(gptrat);

            // Setting the coordinates
            AktualneX = 20;
            AktualneY = 50;

        }

Вот конвертер BodUsekSwitcher (на английском языке, VertexEdgeSwitch):

namespace Editor.Converters
{
    public class SwitchListConverter : IMultiValueConverter
    {
        static int poslednyTyp = 0;
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            // Switching between Vertex and Edge Template
            if (poslednyTyp == 0)
            {
                poslednyTyp = 1;
                return values[1];       // EdgeList
            }
            else
            {
                poslednyTyp = 0;
                return values[0];       // VertexList
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Вот неправильный результат: https://imgur.com/a/AHV3rU2.Я установил X и Y на 20 и 50 соответственно (как вы можете видеть в конструкторе в TratViewModel), поэтому они должны быть немного вправо и вниз.

Мне также любопытно, есть ли каждая вершина ина холсте нарисован край.

Если кто-то знает, как ориентироваться в этом беспорядке, помогите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...