How to make itemtemplate aware of its containing t

2019-03-01 22:03发布

问题:

I want this Ellipse to get its coordinates from its corresponding BallViewModel, and to use them to determine its location inside a canvas. The list of balls is bound to List<BallVM> in the mainviewmodel and thus I chose an itemsControl which has a canvas panel.

Is this approach correct?

If I try to bind to X and Y inside an itemcontainerstyle, then it's not specific to a certain ball.

No matter what I set in the Canvas.bottom or canvas.left properties the ellipse is always at the top left.

<Grid>
        <ItemsControl ItemsSource="{Binding Balls}" Background="red">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas MouseMove="Canvas_MouseMove" Background="Blue"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type VM:BallVM}">
                    <Ellipse Canvas.Bottom="{Binding Y}" Canvas.Left="{Binding X}" Width="100" Height="100" Fill="Red"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>

回答1:

When you use an ItemTemplate with an ItemControls it does not directly put your Elippses on the Canvas but wraps them into an ContentPresenter. So you have to apply your canvas.Bottom/Left properties on the ItemsPresenter. You can can do this with the ItemContainerStyle:

<ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Bottom" Value="{Binding Y}" />
                <Setter Property="Canvas.Left" Value="{Binding X}" />                    
            </Style>
 </ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type VM:BallVM}">
                <Ellipse Width="100" Height="100" Fill="Red"/>
            </DataTemplate>
 </ItemsControl.ItemTemplate>


标签: wpf mvvm