Reputation: 302
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.
Upvotes: 2
Views: 6237
Reputation: 1
<ListBox ItemsSource="{Binding WeeklyWeather}"
SelectedItem="{Binding SelectedDailyWeather, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Day}"/>
<Image Source={Binding WheatherPicturePath}/>
<TextBlock Text="{Binding Temperature}"/>
<TextBlock Text="{Binding Description}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<!-- use this place to design how container normally looks like -->
<Border
x:Name="Border"
Margin="0"
Padding="18,10,2,8"
Background="Transparent"
BorderThickness="1"
CornerRadius="0"
SnapsToDevicePixels="True">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="{DynamicResource ListBoxItemSelectedBackgroundThemeBrush}" />
<Setter Property="Foreground" Value="{DynamicResource ListBoxItemSelectedForegroundThemeBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Upvotes: 0
Reputation: 181
You can set a simple ListBox template like this:
<ListBox Grid.Row="1" x:Name="DailyWeatherListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<!--Insert XAML for One Item-->
<Label Content="{Binding}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBoxItem>Item 1</ListBoxItem>
<ListBoxItem>Item 2</ListBoxItem>
</ListBox>
In most real world scenarios where there is more then once piece of information per item to be displayed you would define how you want your data to be displayed through a DataTemplate
. For example if I wanted to display both the high temperature and the low temperature and style them separately: I would first create a DailyWeather
model in c# and create a DataTemplate
for it, like so:
public class DailyWeather
{
public int High { get; set; }
public int Low { get; set; }
// You Would Add All Your Other Data You Want to Display Here
}
In your page resources (or another resource dictionary like in App.xaml):
<Window.Resources>
<DataTemplate DataType="{x:Type DailyWeather}">
<Grid>
<StackPanel>
<Label FontSize="18" Content="{Binding High}"/>
<Label FontSize="14" Content="{Binding Low}"/>
</StackPanel>
</Grid>
</DataTemplate>
</Window.Resources>
On your ListBox
no ItemTemplate
is required ...
<ListBox Grid.Row="1" x:Name="DailyWeatherListBox"/>
... because once you set the source to a List<DailyWeather>
, (or do a binding like Siim Haas's answer suggests) your program will find the DataTemplate
we defined for a DailyWeather
object that we included in the resources.
Upvotes: 2
Reputation: 505
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
Upvotes: 5