DataTemplate обеспечивает правильный результат для первого элемента в списке, а затем неверный для второго элемента в WPF - PullRequest
0 голосов
/ 03 ноября 2011

В моем контроле следующий предмет:

<Canvas Name="canvasTrack" Height="{Binding CanvasHeight}" Width="{Binding CanvasWidth}"> 
   <ItemsControl  
         ItemsSource="{Binding Path=CurrentSegments}" 
         ItemTemplate="{StaticResource BegSegmentTemplate}">
    </ItemsControl>
</Canvas>

и следующие DataTemplate:

<DataTemplate x:Key="BegSegmentTemplate">
    <Ellipse Height="10" Width="10" Margin="{Binding EntryPoint}" Fill="Black" HorizontalAlignment="Center" />
</DataTemplate>

Затем я привязал его к ObservableCollection, в котором есть два предмета. Когда я запускаю программу, появляются два эллипса. Первый находится в правильном месте на моем холсте, а второй - в «случайном» месте. Я проверил числа, которые связаны, и все кажется нормальным. Чего мне не хватать?

Ответы [ 2 ]

4 голосов
/ 03 ноября 2011

По умолчанию ItemsControl проходит по всем элементам и помещает каждый из них в StackPanel, поэтому ваша конечная разметка в основном выглядит следующим образом:

<Canvas>
    <StackPanel>
        <ContentPresenter>
            <Ellipse Margin="{Binding EntryPoint}" />
        </ContentPresenter>
        <ContentPresenter>
            <Ellipse Margin="{Binding EntryPoint}" />
        </ContentPresenter>
    </StackPanel>
</Canvas>

Если вы хотите перебрать элементы и поместить их в Canvas на основе некоторого связанного значения, вам нужно перезаписать ItemsPanelTemplate, чтобы использовать Canvas вместо StackPanel, и применить свое позиционирование в ItemContainerStyle, так что вы устанавливаете позиционирование на ContentPresenter, а не на Ellipse

Это сделает ваш конечный результат похожим на:

<Canvas>
    <ContentPresenter Margin="{Binding EntryPoint}">
        <Ellipse />
    </ContentPresenter>
    <ContentPresenter Margin="{Binding EntryPoint}">
        <Ellipse />
    </ContentPresenter>
</Canvas>

Пример кода для достижения этой цели:

<ItemsControl ItemsSource="{Binding CurrentSegments}">

    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <!-- ItemContainerStyle -->
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Margin" Value="{Binding EntryPoint}" />
        </Style>
    </ItemsControl.ItemContainerStyle>

    <!-- ItemTemplate -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse Height="10" Width="10" Fill="Black" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>

См. эту ссылку для некоторых образцов, использующих ItemsControl

0 голосов
/ 03 ноября 2011

Попробуйте указать ItemsPanel в вашем ItemsControl:

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <Canvas />
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
...