Silverlight ListBox, ItemsControl itemspanel canvas, item position

The problem is:
How can I use the Canvas in ItemsPanelTemplate and position the item on the right coordinate?

  • First solution I tryed:
    <ListBox ItemsSource="{Binding Data}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <Grid Canvas.Top="{Binding Punto.Y}" Canvas.Left="{Binding Punto.X}">
                            <ContentPresenter />
                        </Grid>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                ...
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    
  • Second test:
    <ListBox ItemsSource="{Binding Data}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Canvas.Top" Value="{Binding Punto.Y}" />
                <Setter Property="Canvas.Left" Value="{Binding Punto.X}" />
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                ...
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    
  • Results:
    The first solution will not work because in Silverlight not permit Binding on Attached Property
    The second solution will not work because Silverlight 4.0 not support Binding on Setter

The working Solution I’ve fond are these:

  • Working Solution 1
    Use SetterValueBindingHelper a class created to do this, using this class.

    <ListBox ItemsSource="{Binding Data}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Helpers:SetterValueBindingHelper.PropertyBinding"> 
                    <Setter.Value> 
                        <Helpers:SetterValueBindingHelper> 
                            <Helpers:SetterValueBindingHelper Type="Canvas" Property="Left" Binding="{Binding Punto.X}" /> 
                            <Helpers:SetterValueBindingHelper Type="Canvas" Property="Top" Binding="{Binding Punto.Y}" /> 
                        </Helpers:SetterValueBindingHelper> 
                    </Setter.Value> 
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                ...
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    
  • Working Solution 2 (preferred)
    Use a grid instead a Canvas and use margin prop instead of Canvas.Top or Canvas.Left attached property.

    <ListBox ItemsSource="{Binding Data}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="{Binding Punto, Converter={StaticResource MarginConverter}}">
                    ...
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    

    Obviously I’ve created a Converter that return new Thickness(PointValue.Left, PointValue.Top, 0, 0)

  • Working Solution 3

    <ListBox ItemsSource="{Binding Data}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RenderTransform> 
                        <TranslateTransform X="{Binding Punto.X}" Y="{Binding Punto.Y}" /> 
                    </Grid.RenderTransform> 
                    ...
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    
  • Note
    This is the simplest working solution, but introduces a small annoyance because the items will put on the left upper corner and than they will move to the right position.
    This movement catched by eye.

    So the solution I preferred it the Working solution 2

Annunci

Informazioni su Andrea Regoli

Project Manager .Net Developer WPF WP7 Asp.Net c# javascript ajax SQL sharepoint
Questa voce è stata pubblicata in c#, Silverlight, WP7, xaml e contrassegnata con , , , , , , . Contrassegna il permalink.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...