0
votes

I'm currently working on a .NET 4.7.1 application. I use a XAML WPF UI. I need to show rectangles on a canvas according to the values in a list in the bound view model.

I can show a static rectangle on my canvas, nevertheless I don't know how to show the rectangles from the ItemsControl DataTemplate. Also, I need to use a certain style for my rectangles. I defined the style in the Canvas.Resources for now.

My current coding looks like this:

<Canvas x:Name="canvas" Grid.Row="2" ClipToBounds="True" Background="Gainsboro">
    <Canvas.Resources>
        <Style TargetType="Rectangle">
            <Setter Property="Fill">
                <Setter.Value>
                    <DrawingBrush TileMode="Tile"
                                  Viewport="0,0,2,5" ViewportUnits="Absolute"
                                  Viewbox="0,0,2,30" ViewboxUnits="Absolute">
                        <DrawingBrush.Transform>
                            <RotateTransform Angle="45"/>
                        </DrawingBrush.Transform>
                        <DrawingBrush.Drawing>
                            <GeometryDrawing>
                                <GeometryDrawing.Pen>
                                    <Pen Brush="Red" Thickness="10"/>
                                </GeometryDrawing.Pen>
                                <GeometryDrawing.Geometry>
                                    <LineGeometry StartPoint="0,15" EndPoint="30,15"/>
                                </GeometryDrawing.Geometry>
                            </GeometryDrawing>
                        </DrawingBrush.Drawing>
                    </DrawingBrush>
                </Setter.Value>
            </Setter>
        </Style>
    </Canvas.Resources>
    <!-- The static Rectangle works fine -->
    <!--<Rectangle Width="100" Height="100" Canvas.Left="100" Canvas.Top="100"/>-->
    <ItemsControl ItemsSource="{Binding RItems}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Rectangle Width="{Binding Width}" Height="{Binding Height}" Canvas.Left="{Binding Y}" Canvas.Right="{Binding X}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>        
    </ItemsControl>

    <Grid Width="{Binding ActualWidth, ElementName=canvas}" Height="{Binding ActualHeight, ElementName=canvas}">
        <Label Content="Beginning" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Left">
            <Label.LayoutTransform>
                <RotateTransform Angle="270"/>
            </Label.LayoutTransform>
        </Label>
        <Label Content="End" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Right">
            <Label.LayoutTransform>
                <RotateTransform Angle="270"/>
            </Label.LayoutTransform>
        </Label>
    </Grid>
</Canvas>

My basic RItems collection in the View Model looks like this:

public List<RItem> RItems { get; set; } = new List<RItem>
{
    new RItem
    {
        X = 100,
        Y = 100,
        Width = 100,
        Height = 100
    }
};

Do you know what I'm doing wrong? How can I show my RItem from the View Model class on the Canvas?

Thanks a lot!!

1

1 Answers

1
votes

The canvas should be inside the itemscontrol as it's itemspanel.

Something very roughly like:

<ItemsControl ItemsSource="{Binding RItems}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <Canvas />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
       .....
    </DataTemplate>
  </ItemsControl.ItemTemplate>
  <ItemsControl.ItemContainerStyle>
    <Style>
      <Setter Property="Canvas.Left" Value="{Binding Left}" />
      <Setter Property="Canvas.Top" Value="{Binding Top}" />
    </Style>
  </ItemsControl.ItemContainerStyle>
</ItemsControl>

Note also that each item goes inside a container and it is this which has to be positioned on the canvas.

I'm not sure why your grid is bound to the size of the canvas. Put the itemcontrol inside the grid and it'll fill the grid.