如何在WPF中为列表框设置模板(Windows 10 Weather)

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

我正在尝试使用 C#WPF 中创建一个 Windows 10 天气应用程序。我需要一个 Listbox 来显示最近 10 天的天气部分。我必须为 Listbox 项设置模板。我试过这个:

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

查看 Windows 10 天气。我把这张图废了Windows 10. 我也不知道如何在 Listbox 角设置 Scrollbar。如果您能提供帮助,我将不胜感激。

您可以像这样设置一个简单的列表框模板:

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

在大多数现实世界场景中,每个项目要显示的信息不止一次,您可以通过 DataTemplate 定义数据的显示方式。例如,如果我想同时显示高温和低温并分别设置它们的样式:我将首先在 c# 中创建一个 DailyWeather 模型并为其创建一个 DataTemplate,如下所示:

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
}

在您的页面资源中(或 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>

您的 ListBox 不需要 ItemTemplate ...

<ListBox Grid.Row="1" x:Name="DailyWeatherListBox"/>

... 因为一旦您将源设置为 List<DailyWeather>,(或像 Siim Haas 的回答建议的那样进行绑定)您的程序将找到我们为 [=15 定义的 DataTemplate =] 我们包含在资源中的对象。

我会这样开始:

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

这里有一些关于如何进行这些绑定的想法。

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; }
    //...
}

您的代码隐藏方法可能不同,但它们需要到位以便您使用这些绑定。

对于这样的滚动条,我会研究 Change scrollviewer template in listbox