一个包含UserControl元素的ItemsControl

5

我对这个问题有些摸不着头脑,已经查找了一些资料,但没有找到相关的内容。我的目标是在当前窗口上创建一个ItemsControl,所以当用户点击窗口上的“添加产品”按钮时,它会以水平方式将一个UserControl添加到屏幕上。

首先,我正在使用MVVM模式,并且我有一个PricingViewModel,它是我的主窗口的ViewModel。我有第二个视图模型,名为ComparisonViewModel,它是我想要在用户每次点击PricingView上的“添加产品”按钮时显示的UserControl的ViewModel。进入我的代码,我有一个声明的ObservableCollection和我的AddComparison方法。集合在VM的构造函数中实例化。

    public ObservableCollection<ComparisonViewModel> Products { get { return _products; } }

    public void AddComparison()
    {
        var products = IoC.Get<ComparisonViewModel>();
        Products.Add(products);
    }

接下来,在 PricingView 中,我使用 ItemsControl 绑定到 PricingViewModel 中的集合:

            <ItemsControl ItemsSource="{Binding Path=Products}" >
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>

当我运行它并点击添加后,它只显示集合名称。如何在用户点击“添加比较”时实际弹出新的“比较用户控件”?非常感谢您提前的帮助!

2个回答

5

我发现需要告诉ItemsControl两件事情... 第一是ItemsControl所代表的"thing"类型:

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

第二个问题是如何显示控件:

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <c:Widget Margin="5" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>

最终代码如下:
    <ItemsControl ItemsSource="{Binding Path=DynamicItems}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <c:Widget Margin="5" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

您还需要在窗口声明部分添加对控件命名空间的引用:

您还需要在窗口声明部分添加对控件命名空间的引用:

    xmlns:c="clr-namespace:IHateEverything.Controls"

4
您需要设置ItemTemplate,这样ItemsControl就知道如何渲染集合中的每个项(默认情况下,它只显示调用.ToString()的结果)。
        <ItemsControl ItemsSource="{Binding Path=Products}" >
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

           <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type namespace:ComparisonViewModel}">
                    <!-- EXAMPLE -->
                    <Border BorderBrush="Black"
                            BorderThickness="2">
                          <DockPanel Orientation="Horizontal">
                                 <TextBlock Text="{Binding ComparisonResult}"
                                            DockPanel.Dock="Right" />
                                 <TextBlock Text="{Binding Name}" 
                                            DockPanel.Dock="Left" />
                          </DockPanel>
                    </Border>
                </DataTemplate>
           </ItemsControl.ItemTemplate>

        </ItemsControl>

嗯,DataTemplate没有TargetType属性,我也尝试将其添加为<UserControl/>,但仍无法呈现。你能不能再具体一点? - justin peterson
@JustinPeterson 对不起,应该是 DataType 而不是 TargetType - Jay
糟糕,它仍然无法渲染。 <DataTemplate DataType="{x:Type Leads:ComparisonViewModel}"> <UserControl Width="200" Height="450"/> </DataTemplate> - justin peterson
@JustinPeterson 你实际上需要定义用于显示“ComparisonViewModel”的用户界面。请参考我的编辑。 - Jay
那不就是从“Comparison”对象中获取数据吗?这并不会显示我创建的UserControl本身。新的UI部分已经作为ComparisonView创建了。我知道你可以在里面模拟一个新的UI。我可能最终只能这样做。 - justin peterson
@JustinPeterson 好的,你可以使用 ComparisonView。在 DataTemplate 中,使用 <namespace:ComparisonView…> 代替 <UserControl …> - Jay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接