【问题标题】:WPF listbox with canvas only showing last item带有画布的 WPF 列表框仅显示最后一项
【发布时间】:2017-08-31 19:39:35
【问题描述】:

我有一个带有 Canvas 作为 ItemsPanel 的 ListBox。

<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>

问题在于,每当我向 Listbox 绑定的 Items 添加新项目时,它只会在屏幕上显示该新项目。列表中的所有先前项目均未显示。我可以看到所有项目确实都在 Items 列表中,并且 ListBoxItems 已添加到可视化树中。但我看不到他们。只添加了最后一项。

这是运行的样子(只显示一项)

这是它在设计器中的样子以及运行时的样子

有什么建议吗?

更新 1

设计师使用的代码是这样的

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);

        ... 

    }
}

添加到 Items (ObservableCollection) 的真正代码是这样的。它是拖放操作的一部分。

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);

【问题讨论】:

  • 项目是列表还是 ObservableCollection?你的代码对我来说很好。
  • 您还应该显示实际添加项目的代码。它与设计模式代码有何不同?
  • @EdPlunkett 这是一个 ObservableCollection,请查看我的更新
  • @Clemens 添加了在设计和运行中添加的代码
  • 如何排除DrawingPanelViewModel 有两个实例的可能性?我要研究的另一种可能性是,comp 可能每次都是同一个对象。

标签: wpf canvas listbox


【解决方案1】:

XAML 工作正常,您已确认只创建了一个视图模型副本,因此只有一个 Items 集合,并且第一个 drop 工作正常。

看着你的代码,让我眼前一亮的是这一行:

var comp = e.Data.GetData(typeof(DrawingComponent).FullName) as DrawingComponent;

这不是创建DrawingComponent;它是从其他东西放入的帽子中取出一个。我会在那里放一个断点,看看你是否真的在Items 中获得了多个项目,但它们都是相同的实际对象实例,具有相同的属性值。

或者我直接进入开始拖动的代码,并确保每次都创建一个新的DrawingComponent——否则每次都在下降结束。不过,在拖动端执行此操作似乎更好,因为您可以从不同来源拖动 DrawingComponent 的不同子类,并且放置代码不需要担心它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2019-12-02
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多