Reputation: 355
I have a ListBox with a Canvas as ItemsPanel.
<UserControl.Resources>
<DataTemplate x:Key="itemTemplate">
<Border BorderBrush="LightBlue" BorderThickness="1">
<Grid Margin="0,2,2,2" Width="{Binding Width}" Height="{Binding Height}">
<Rectangle Cursor="Hand" Fill="AliceBlue"
MouseDown="Rectangle_MouseDown"
MouseMove="Rectangle_MouseMove"
MouseUp="Rectangle_MouseUp"/>
<Label Content="{Binding Name}" Margin="5" IsHitTestVisible="False"/>
</Grid>
</Border>
</DataTemplate>
</UserControl.Resources>
<ListBox ItemsSource="{Binding Items}"
x:Name="listBox"
SelectionMode="Extended"
ItemTemplate="{StaticResource itemTemplate}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="Transparent"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
The problem is that whenever I add a new item to Items, which Listbox is binding to, it only shows that new item on screen. All previous items in the list are not shown. I can see that all the items are indeed in the Items list, and ListBoxItems are added to the visual tree. But I cannot see them. Only the last item added.
This is what it looks like running (only ever one item is shown)
This is what it looks like in designer and how it should look like running
Any suggestions?
UPDATE 1
The code the designer uses is this
public class DrawingPanelViewModelMockup: DrawingPanelViewModel
{
public DrawingPanelViewModelMockup()
{
//Pc subclasses DrawingComponent
var pc = new Pc();
pc.Name = "PC";
pc.X = 20;
pc.Y = 40;
pc.Width = 100;
pc.Height = 50;
Items.Add(pc);
...
}
}
And the real code that adds to Items (ObservableCollection) is this. It's part of a Drag-n-drop operation.
var comp = e.Data.GetData(typeof(DrawingComponent).FullName) as DrawingComponent;
var drawingPanelVm = ServiceLocator.Current.GetInstance<DrawingPanelViewModel>();
comp.X = mousePos.X;
comp.Y = mousePos.Y;
comp.Width = 100;
comp.Height = 50;
drawingPanelVm.Items.Add(comp);
Upvotes: 1
Views: 471
Reputation: 37066
The XAML works fine, and you've confirmed that there's only one copy of the viewmodel created, hence only one Items
collection, and the first drop works.
Looking at your code, what jumps out at me is this line:
var comp = e.Data.GetData(typeof(DrawingComponent).FullName) as DrawingComponent;
That's not creating a DrawingComponent
; it's pulling one out of a hat that something else put it into. I'd put a breakpoint in there and see if you're actually getting multiple items in Items
, but they're all the same actual object instance, with the same property values.
Or I'd just go straight to the code that starts the drag, and make sure you're creating a new DrawingComponent
every time -- or else create a clone each time on the drop end. Doing it on the drag end seems better though, because then you can drag different subclasses of DrawingComponent
from different sources and the drop code doesn't need to worry about it.
Upvotes: 1