Search code examples
c#uwppivotuwp-xamlstackpanel

C# UWP Adding scrollbar,margin,border to pivotItem


I am creating Windows UWP app that displays weather forecasts from a nestedlist sortedDays . It contains days on the Outer list and hourly forecasts in the inner list. (using pivot)I am trying to display in each pivotItem, a separate stackPanel for every hourly forecast so that each pivotItem will have numerous stackPanels of hourly forecast.

Unfortunately my data is running off the bottom of the screen and I cannot seem to get a scroll bar working. I have also been struggling with adding any form of margin or boarder around the hourStack stackPanels. As the data is is coming from a nested list generated from an API I feel it must be added through c# code and not xaml(open to opinions). I have looked up the documentation but cant find anything that works through c#

 //dynamically add a pivot item
        PivotItem pvt;
        ScrollViewer scroll;

        //loop through SortedDays to seperate Day and hour forecasts 
        int xCount = 0, yCount = 0;
        foreach (var sd in myForecast.SortedDays)
        {// Define a ScrollViewer

            scroll = new ScrollViewer
            {
                VerticalScrollBarVisibility = ScrollBarVisibility.Visible
            };
            pvt = new PivotItem
            {
                Header = myForecast.SortedDays[xCount][0].dayOfWeek

            };
            var dayStack = new StackPanel();

            foreach (var sh in sd)
            {
                var hourStack = new StackPanel
                {
                    HorizontalAlignment = HorizontalAlignment.Center

                };

                var timeBlock = new TextBlock
                {
                    Text = myForecast.SortedDays[xCount][yCount].dtime,
                    FontSize = 30
                };
                hourStack.Children.Add(timeBlock);

                var tempBlock = new TextBlock
                {
                    Text = "Tempeture (c)\t:" + System.Convert.ToString(Math.Truncate((myForecast.SortedDays[xCount][yCount].temp - 273.15) * 100) / 100)
                };
                hourStack.Children.Add(tempBlock);

                var descBlock = new TextBlock
                {
                    Text = myForecast.SortedDays[xCount][yCount].desc
                };
                hourStack.Children.Add(descBlock);

                var windBlock = new TextBlock
                {
                    Text = "Windspeed\t:" + System.Convert.ToString(myForecast.SortedDays[xCount][yCount].windSpeed)
                };
                hourStack.Children.Add(windBlock);

                var humBlock = new TextBlock
                {
                    Text = "Humidity\t:" + System.Convert.ToString(myForecast.SortedDays[xCount][yCount].humidity)
                };
                hourStack.Children.Add(humBlock);

                // append hourStack to dayStack
                yCount++;
                dayStack.Children.Add(hourStack);
            }
            scroll.Content = dayStack;
            // set dayStack as pivots content
            pvt.Content = scroll;

            // add pivotItem to pivot
            pvtWeather.Items.Add(pvt);

            pvt = null;
            xCount++;
            yCount = 0;
        }

WeatherPage.xaml

<Page
x:Class="WeatherForecast.WeatherPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WeatherForecast"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Pivot x:Name="pvtWeather"  Margin="100,100,100,100" Height="1200" HorizontalAlignment="Center" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.BringIntoViewOnFocusChange="True">



    </Pivot>
</Grid>

enter image description here


Solution

  • Before trying to set above properties code behind, actually all the elements and styles used in above code snippet could be defined in XAML. For your scenario, PivotItem is strongly recommended to bind with data sources. Details for binding please reference this tutorial. And a nested list could be bound to Pivot control.

    Just for example, you may define the entities as follows:

    public class Daylist
    {
        public string Day { get; set; }
        public ObservableCollection<TimeTemperature> Temperatures { get; set; }
    }
    
    public class TimeTemperature
    {
        public string currenttime { get; set; }
        public string winSpeed { get; set; }
        public string humidity { get; set; }
        public string temperature { get; set; }
    }
    

    So that the nested list could be created as follows:

    public ObservableCollection<Daylist> daylists { get; set; } 
    public MainPage()
    {
        this.InitializeComponent();
        daylists = new ObservableCollection<Daylist>
        {
            new Daylist {Day="Wednesday" ,Temperatures= new ObservableCollection<TimeTemperature>
            {
                new TimeTemperature {currenttime="2018-3-14 00:00:00",temperature="7.72",winSpeed="11.67" ,humidity=".95"},
                new TimeTemperature {currenttime="2018-3-14 01:00:00",temperature="7.72",winSpeed="11.67" ,humidity=".95" },
                new TimeTemperature {currenttime="2018-3-14 02:20:00",temperature="7.72",winSpeed="11.67" ,humidity=".95"}
                ...
            }},
            new Daylist {Day="Friday" ,Temperatures= new ObservableCollection<TimeTemperature>
            {
                 new TimeTemperature {currenttime="2018-3-14 00:00:00",temperature="7.72",winSpeed="11.67" ,humidity=".95" }
            }}
        };
    }
    

    And now we can define the elements in XAML and bind data source to Pivot and PivotItem, the layout can be simply updated. For your requirements, using a ListView for Pivot.ItemTemplate to show the data , it will auto scroll when records are overflow. You can also add Margin and other properties as you want.

    <Pivot x:Name="Pivot1" ItemsSource="{x:Bind daylists}">
        <Pivot.HeaderTemplate>
            <DataTemplate x:DataType="local:Daylist">
                <TextBlock Text="{x:Bind Day}" />
            </DataTemplate>
        </Pivot.HeaderTemplate>
        <Pivot.ItemTemplate>
            <DataTemplate x:DataType="local:Daylist">
                <ScrollViewer>
                    <ListView ItemsSource="{x:Bind Temperatures}">
                        <ListView.ItemTemplate>
                            <DataTemplate x:DataType="local:TimeTemperature">
                                <Grid Margin="20">
                                    <Grid.RowDefinitions>
                                        <RowDefinition />
                                        <RowDefinition />
                                        <RowDefinition />
                                        <RowDefinition />
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition />
                                        <ColumnDefinition />
                                    </Grid.ColumnDefinitions>
                                    <TextBlock
                                        Grid.Row="0"
                                        Grid.ColumnSpan="2"
                                        Text="{x:Bind currenttime}" />
                                    <TextBlock
                                        Grid.Row="1"
                                        Grid.Column="0"
                                        Text="winSpeed:" />
                                    <TextBlock
                                        Grid.Row="1"
                                        Grid.Column="1"
                                        Text="{x:Bind winSpeed}" />
                                    <TextBlock
                                        Grid.Row="2"
                                        Grid.Column="0"
                                        Text="humidity:" />
                                    <TextBlock
                                        Grid.Row="2"
                                        Grid.Column="1"
                                        Text="{x:Bind humidity}" />
                                    <TextBlock
                                        Grid.Row="3"
                                        Grid.Column="0"
                                        Text="temperature:" />
                                    <TextBlock
                                        Grid.Row="3"
                                        Grid.Column="1"
                                        Text="{x:Bind temperature}" />
                                </Grid>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </ScrollViewer>
            </DataTemplate>
        </Pivot.ItemTemplate>
    </Pivot>
    

    More details please reference the official sample.