Search code examples
c#wpftemplateslistboxlistboxitem

How to set template for listbox in WPF(Windows 10 Weather)


I am trying to create a Windows 10 weather application in WPF using C#. I need to have a Listbox to display recent 10 day weather section. I must set template for Listbox items. I tried this:

<ListBox Grid.Row="1" x:Name="DailyWeatherListBox">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel>
                <!--...-->
            </StackPanel>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

This is the recent 10 day weather section (Windows 10 Weather)

Look the Windows 10 Weather. I put this image for disuse Windows 10. I also don't know how to set Scrollbar in the Listbox corners. I would be very thankful if you could help.


Solution

  • I would start off something like this:

    <ListBox ItemsSource="{Binding WeeklyWeather}"
             SelectedItem="{Binding SelectedDailyWeather, Mode=TwoWay}">
    
        //Use ItemTemplate to set how item looks "inside"
        //I'll leave design details for you
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Day}"/>
                    <Image Source={Binding WheatherPicturePath}/>
                    <TextBlock Text="{Binding Temperature}"/>
                    <TextBlock Text="{Binding Description}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    
        //ItemsPanel defines container for items. It can be StackPanel, Wrapanel, Grid, etc
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel IsItemsHost="True" Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            //You use this place to design how container normally looks like
                            <Border Background="White">
                                //DataTemplate defined above is placed in ContentPresenter
                                <ContentPresenter />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    //Here we catch "IsSelected" event and re-design our template to visually reflect "selected"
                    <Trigger Property="IsSelected" Value="true">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                    <Border Background="Gray">
                                        <ContentPresenter />
                                    </Border>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
    
    </ListBox>
    

    Here are couple ideas how for those bindings.

    public class WeatherViewModel
    {
        public string Day { get; set; }
        public string WheatherPicturePath { get; set; }
        public string Temperature { get; set; }
        public string Description { get; set; }
    }
    
    public class BindedDataContext
    {
        public ObservableCollection<WeatherViewModel> WeeklyWeather { get; set; }
        public WeatherViewModel SelectedDailyWeather { get; set; }
        //...
    }
    

    Your approaches for code-behind may differ, but they need to be in place for you to use those bindings.

    For such scrollbar I would look into Change scrollviewer template in listbox