【问题标题】:How to set template for listbox in WPF(Windows 10 Weather)如何在 WPF(Windows 10 天气)中为列表框设置模板
【发布时间】:2019-04-30 06:35:52
【问题描述】:

我正在尝试使用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。如果您能提供帮助,我将不胜感激。

【问题讨论】:

    标签: c# wpf templates listbox listboxitem


    【解决方案1】:

    我会这样开始:

    <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

    【讨论】:

      【解决方案2】:

      你可以像这样设置一个简单的 ListBox 模板:

      <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&lt;DailyWeather&gt;,(或像 Siim Haas 的回答所建议的那样进行绑定),您的程序将找到我们为 DailyWeather 对象定义的 DataTemplate,该对象包含在资源。

      【讨论】:

      • 请注意,当显式使用 DataTemplate 时,不要设置 DataTemplate 的 DataType,例如在 ItemsControl 的 ItemTemplate 中。 DataType 将被简单地忽略。仅当您希望自动选择 DataType 时,设置 DataType 才有意义。然后必须将 DataTemplate 放入 ResourceDictionary。
      • @Clemens 我已经编辑了这篇文章,以使我想说的更清楚。我通常设置 DataType,因为 Visual Studio 会给你智能感知(至少对于 UWP 上的 ListView - 我假设 WPF 也是如此),从长远来看,这会让事情变得更容易。我不太明白你所说的“自动选择”是什么意思。
      • 自动模板选择是 DataType 属性的唯一用途。将 DataTemplate 放入 ResourceDictionary(例如 Window.Resources),然后将 DailyWeather 对象分配给例如ContentControl 的 Content 属性。该控件现在将自动为 ContentControl 的 ContentTemplate 选择您的 DataTemplate。因此,您也不必显式设置 ListBox 的 ItemTemplate。现在你的回答听起来好像是 necessary 设置 DataType (即使 DataTemplate 中的绑定工作)。这不是真的。
      • 查看 MS Docs 上的 Remarks当您将此属性设置为数据类型而不指定 x:Key 时,DataTemplate 会自动应用于该类型的数据对象。我>
      • 啊,有道理。因此,您可以(/应该)定义“DailyWeather”对象在某个普遍地点的样子;然后设置 ListBox 的源(或其他控件,如 ListView 等),它会自行获取 DataTemplate。如果是这样,那就更有意义了。感谢您提及:我还有很多东西要学。
      猜你喜欢
      • 1970-01-01
      • 2016-11-25
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多