1

I am working on a simple node editor, something like this (for me it is a model program). I have two windows in XAML with different solutions. In the first case (still not completed, but for demonstration), I am using templates inside grid:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Grafika"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="Grafika.MainWindow"
    Title="MainWindow" Height="350" Width="525">

<Window.Resources>
    <DataTemplate DataType="{x:Type local:Node}">
        <Thumb Width="{Binding Width}" Height="{Binding Height}" DragDelta="Thumb_DragDelta">
            <Thumb.Template>
                <ControlTemplate>
                    <Border Background="CadetBlue"/>
                </ControlTemplate>
            </Thumb.Template>
        </Thumb>

    </DataTemplate>
    <DataTemplate DataType="{x:Type local:Connector}">
        <Line Name="Connection" Stroke="Red" StrokeThickness="3"  X1="{Binding StartX}" Y1="{Binding StartY}" X2="{Binding StopX}" Y2="{Binding StopY}"/>
    </DataTemplate>    

</Window.Resources>

<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>

<Grid x:Name="mrizka">

    <Border x:Name="obrys" Width="200" Height="150" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Aqua" BorderBrush="Red" d:IsHidden="True"/>
    <Path Data="M 25,25 H 250 V 250" Stroke="Black" d:IsHidden="True"/>

    <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
        <Border>
            <Border.Background>
                <VisualBrush TileMode="Tile" Viewport="0,0,50,50" ViewportUnits="Absolute" Viewbox="0,0,50,50" ViewboxUnits="Absolute">
                    <VisualBrush.Visual>
                        <Rectangle Stroke="Black" StrokeThickness="1" Height="50" Width="50"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Border.Background>
        </Border>
    </ScrollViewer>

    <ItemsControl ItemsSource="{Binding NodeList}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Y}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>

    <ItemsControl ItemsSource="{Binding Connections}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

</Grid>
</Window>

with output

In second case, I am taking templates into ListBox (with combination of CompositeCollection) and I thought it would work since the previous case worked correctly. However, when I launch the program nothing shows.

Code:

<Window x:Class="Grafika.Test1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Grafika"
    mc:Ignorable="d"
    Title="Test1" Height="600" Width="800" x:Name="view" >

<Window.Resources>
    <Style TargetType="Control" x:Key="EmptyStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>

<Grid Margin="10">
    <Grid.Resources>
        <CompositeCollection x:Key="Col">
            <CollectionContainer Collection="{Binding DataContext.NodeList, Source={x:Reference view}}"/>
            <CollectionContainer Collection="{Binding DataContext.Connections, Source={x:Reference view}}"/>
        </CompositeCollection>

        <!-- -->
        <DataTemplate DataType="{x:Type local:Node}">
            <Thumb DragDelta="Thumb_DragDelta">
                <Thumb.Template>
                    <ControlTemplate TargetType="Thumb">
                        <Canvas Margin="-10,-10,10,10">
                            <Border Height="{Binding Height}" Width="{Binding Width}" x:Name="rect" Background="Red"  />
                        </Canvas>
                    </ControlTemplate>
                </Thumb.Template>
            </Thumb>
        </DataTemplate>
        <!-- -->

        <!-- -->
        <DataTemplate DataType="{x:Type local:Connector}">
            <Line Stroke="Blue" StrokeThickness="3" X1="{Binding Start.X}" Y1="{Binding Start.Y}" X2="{Binding Stop.X}" Y2="{Binding Stop.Y}" x:Name="Con"/>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding Stop}" Value="{x:Null}">
                    <Setter TargetName="Con" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
        <!-- -->
    </Grid.Resources>

    <ListBox>
        <ListBox.Template>
            <ControlTemplate>
                <Border>
                    <Border.Background>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="1,1" Opacity=".3">
                            <GradientStop Color="Azure" Offset="0"/>
                            <GradientStop Color="Yellow" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.Background>

                    <ScrollViewer VerticalScrollBarVisibility ="Auto" HorizontalScrollBarVisibility="Auto">
                        <Border>
                            <Border.Background>
                                <VisualBrush TileMode="Tile" Viewbox="0,0,50,50" Viewport="0,0,50,50" ViewboxUnits="Absolute" ViewportUnits="Absolute">
                                    <VisualBrush.Visual>
                                        <Rectangle Stroke="DarkGray" StrokeThickness="0.5" Height="50" Width="50"/>
                                    </VisualBrush.Visual>
                                </VisualBrush>
                            </Border.Background>
                        </Border>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </ListBox.Template>

        <ListBox.ItemsSource>
            <StaticResource ResourceKey="Col"/>
        </ListBox.ItemsSource>

        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas IsItemsHost="True" Background="Cornsilk" Height="{Binding AreaHeight}" Width="{Binding AreaWidth}"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>

        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Canvas.Left" Value="{Binding X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Y}"/>
                <Setter Property="FocusVisualStyle" Value="{StaticResource EmptyStyle}"/>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
</Grid>
</Window>

My question is simple: Why is nothing displayed in the second case? Is there anything wrong in XAML or potentionally some binding missing? I don't think that code behind is at fault, since the first case is working.

grek40
  • 13,113
  • 1
  • 24
  • 50
PadloctCZ
  • 37
  • 6
  • did you mean to change `ListBox.ItemTemplate` when you changed `ListBox.Template` in second case? – Bizhan Jul 17 '18 at 11:07
  • Lately yes, however actually I don't see any of nodes/connections in list and I have no idea, where is the error. That's actually priority to me shows objects in the ListBox (I created some nodes and connections when program started). – PadloctCZ Jul 17 '18 at 11:39
  • well, what happens when you change it to ListBox.ItemTemplate? – Bizhan Jul 17 '18 at 11:46

1 Answers1

0

You are setting a new Template for the ListBox without a panel for the items.

If you change the its Template and you don't add a panel that will contain the items, setting ListBox.ItemsPanel won't have any effect.

I've modified the ListBox Template according to your specification, adding a Canvas as container for the items.

<ListBox ItemsSource="{StaticResource Col}">
    <ListBox.Template>
        <ControlTemplate>
            <Border>
                <Border.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1" Opacity=".3">
                        <GradientStop Color="Azure" Offset="0"/>
                        <GradientStop Color="Yellow" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>

                <ScrollViewer VerticalScrollBarVisibility ="Auto" HorizontalScrollBarVisibility="Auto">
                    <Border>
                        <Border.Background>
                            <VisualBrush TileMode="Tile" Viewbox="0,0,50,50" Viewport="0,0,50,50" ViewboxUnits="Absolute" ViewportUnits="Absolute">
                                <VisualBrush.Visual>
                                    <Rectangle Stroke="DarkGray" StrokeThickness="0.5" Height="50" Width="50"/>
                                </VisualBrush.Visual>
                            </VisualBrush>
                        </Border.Background>
                        <Canvas IsItemsHost="True" Background="Cornsilk" Height="{Binding AreaHeight}" Width="{Binding AreaWidth}" />
                    </Border>
                </ScrollViewer>
            </Border>
        </ControlTemplate>
    </ListBox.Template>

    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Canvas.Left" Value="{Binding X}"/>
            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
Babbillumpa
  • 1,854
  • 1
  • 16
  • 21