Мне нужно рисовать шаблонные элементы из 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), поэтому они должны быть немного вправо и вниз.
Мне также любопытно, есть ли каждая вершина ина холсте нарисован край.
Если кто-то знает, как ориентироваться в этом беспорядке, помогите.