Batteredburrito
Batteredburrito

Reputation: 589

UWP/C# ItemsControl Multiple Boxes?

I have had a lot of help so far with creating the correct formatting for an ItemsControl panel and appreciate this communities help so far with helping me troubleshoot coding issues. Im currently at a rather small hurdle where im trying to figure out how to create multiple boxes within the same ItemsControl. Currently the overall view looks like this:

enter image description here

Im a little stumped and would just like a little guidance really as to where to put the other XAML lines. I need it to look like this:

enter image description here

Here is my code currently (its all nested within a Frame):

<ItemsControl ItemsSource="{StaticResource userDataCollection}" Margin="40,40,40,725"  Width="Auto" Height="310">
                    <!-- Changing Orientation of VirtualizingStackPanel -->
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <VirtualizingStackPanel Orientation="Horizontal"/>                            
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>

                    <!-- Change header for ItemsControl -->
                    <ItemsControl.Template>
                        <ControlTemplate>
                            <Border Background="{StaticResource CustomAcrylicDarkBackground}">
                                <StackPanel>
                                    <TextBlock Text="Accounts At A Glance" FontSize="28" Foreground="#b880fc" Padding="12"/>
                                    <ItemsPresenter/>
                                </StackPanel>
                            </Border>
                        </ControlTemplate>
                    </ItemsControl.Template>


                    <!-- Template for each card-->
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid Width="240" Height="240" Background="Gray" Margin="30,0,0,0" VerticalAlignment="Center" Padding="4">

                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>

                                <TextBlock Grid.Row="0" Text="{Binding Name}" HorizontalAlignment="Center" TextAlignment="Center" Width="220" FontSize="24"/>
                                <TextBlock Grid.Row="1" Text="{Binding PayDate}" HorizontalAlignment="Center" TextAlignment="Center" Width="220" FontSize="14" />
                                <TextBlock Grid.Row="2" Text="{Binding NumberOfItems}" HorizontalAlignment="Center" TextAlignment="Center" Width="220" FontSize="14"/>

                            </Grid>


                        </DataTemplate>

                    </ItemsControl.ItemTemplate>
                </ItemsControl>

I really apologise for this, im trying to learn as much as i can as i go. Im mainly stuggling with the XAML formatting and incorperating learning material into my project :/ Any help would be amazing

Upvotes: 0

Views: 181

Answers (2)

Batteredburrito
Batteredburrito

Reputation: 589

It perfect now.

Im an idiot.

I essentially needed to seperate the information presented within the UserData.cs Class. I didnt understand how the information was being read but understand it now. The XAML has been left untouched as it works currently for what i need. It will be update to follow the MVVM format as mentioned by Mac. Here is the UserData.CS class located inside a data folder:

using System.Collections.ObjectModel;

namespace BudgetSheet.Data
{
    public class UserData
    {
        public string Name { get; set; }
        public string PayDate { get; set; }
        public string NumberOfItems { get; set; }
    }

    class UserDataCollection : ObservableCollection<UserData>
    {
        public UserDataCollection()
        {

            // Placeholder, needs to be replaced with CSV or Database information
            this.Add(new UserData()
            {
                Name = "Selected Username",
                PayDate = "Friday",
                NumberOfItems = "ItemAmount Placeholder"
            });
            // Placeholder for user 2
            this.Add(new UserData()
            {
                Name = "Selected Username 2",
                PayDate = "Friday 2",
                NumberOfItems = "ItemAmount Placeholder 2"
            });
            // Placeholder for user 3
            this.Add(new UserData()
            {
                Name = "Selected Username 3",
                PayDate = "Friday 3",
                NumberOfItems = "ItemAmount Placeholder 3"
            });
        }
    }
}

Here is what it was before hand and why there were issues with information display:

using System.Collections.ObjectModel;

namespace BudgetSheet.Data
{
    public class UserData
    {
        public string Name { get; set; }
        public string PayDate { get; set; }
        public string NumberOfItems { get; set; }
    }

    class UserDataCollection : ObservableCollection<UserData>
    {
        public UserDataCollection()
        {

            // Placeholder, needs to be replaced with CSV or Database information
            this.Add(new UserData()
            {
                Name = "Selected Username",

            });
            // Placeholder for user selected PayDate
            this.Add(new UserData()
            {

                PayDate = "Friday",

            });
            // Placeholder for user selected PayDate
            this.Add(new UserData()
            {

                NumberOfItems = "ItemAmount Placeholder"
            });
        }
    }
}

This solution does not provide much flexibility currently but it works for the formatting. Marking as resolved to close the ticket

Upvotes: 0

Mac
Mac

Reputation: 959

I have an alternative approach for your problem. This uses "semi" MVVM approach (browse through the net and study this pattern).

MainPageViewModel.cs

public class MainPageViewModel : INotifyPropertyChanged
{
    private ObservableCollection<User> _userCollection;
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<User> UserCollection
    {
        get => _userCollection;
        set
        {
            _userCollection = value;
            NotifyProperyChanged();
        }
    }

    private void NotifyProperyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public void LoadData()
    {
        UserCollection = new ObservableCollection<User>
        {
            new User
            {
                Name = "John Doe",
                PayDate = DateTime.Now,
                NumberOfItems = 1
            },
            new User
            {
                Name = "John Doe 2",
                PayDate = DateTime.Now,
                NumberOfItems = 1
            },
            new User
            {
                Name = "John Doe 3",
                PayDate = DateTime.Now,
                NumberOfItems = 1
            },
        };
    }
}

The view (got rid of some styling temporarily):

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="using:App1.ViewModels"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    Loaded="MainPage_OnLoaded">

    <Page.DataContext>
        <vm:MainPageViewModel/>
    </Page.DataContext>

    <Grid>
        <ScrollViewer>
            <ItemsControl ItemsSource="{Binding UserCollection, Mode=TwoWay}" Margin="15"  Width="Auto" Height="310">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <!-- Template for each card-->
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid Width="200" Height="100" Background="Gray" Margin="15,0,0,0" VerticalAlignment="Center" Padding="4">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <TextBlock Grid.Row="0" Text="{Binding Name}" HorizontalAlignment="Center" TextAlignment="Center" Width="220" FontSize="24"/>
                            <TextBlock Grid.Row="1" Text="{Binding PayDate}" HorizontalAlignment="Center" TextAlignment="Center" Width="220" FontSize="14" />
                            <TextBlock Grid.Row="2" Text="{Binding NumberOfItems}" HorizontalAlignment="Center" TextAlignment="Center" Width="220" FontSize="14"/>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</Page>

View's code-behind:

namespace App1
{
    public sealed partial class MainPage
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        public MainPageViewModel VM => (MainPageViewModel) DataContext;

        private void MainPage_OnLoaded(object sender, RoutedEventArgs e)
        {
            VM.LoadData();
        }
    }

}

Output: enter image description here Next steps:

  • Apply your styling. Study how to limit grid columns.

  • Improve the code further, in MVVM you shouldn't really have implementations on the code-behind, so study for ICommand, Microsoft.Xaml.Interactivity

Hope this helps.

Upvotes: 1

Related Questions