Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An ItemsControl containing UserControl elements

I'm kind of shooting in the dark on this one and have been looking around but couldn't find much of anything related. Pretty much I am trying to create an ItemsControl on a current Window that I've got, so when the user clicks an "Add Product" button on the window, it will add a UserControl to the screen in a horizontal matter.

For starters I am using an MVVM pattern and I have a PricingViewModel which is my ViewModel for the MAIN window. I have a second view model named ComparisonViewModel, which is the ViewModel for the View of the UserControl that I would like to show everytime the user hits the "Add Product" button on the PricingView. Jumping into my code, I've got a declared ObservableCollection and my AddComparison method. The Collection is instantiated in the constructor of the VM.

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

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

Next, I've got and ItemsControl in the PricingView that binds to that collection in the PricingViewModel:

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

I run it and after hitting add, it just shows the collection name. How can I actually get it to Pop up with a new Comparison User Control when the user hits Add Comparison? Thanks a ton for the help in advance!

like image 746
justin peterson Avatar asked Sep 19 '12 00:09

justin peterson


2 Answers

You'll want to set the ItemTemplate so the ItemsControl knows how to render each item in the collection (by default, it is just displaying the result of calling .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>
like image 115
Jay Avatar answered Oct 26 '22 06:10

Jay


I have found that I needed to tell the ItemsControl two things... First is what type of "thing" the ItemsControl is:

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

And the second is how to display the Control:

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

The final code looks like:

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

You also need to add a reference to your control namespace in the window declaration stuff:

    xmlns:c="clr-namespace:IHateEverything.Controls"
like image 37
Carl Forgey Avatar answered Oct 26 '22 06:10

Carl Forgey