[WPF] Collection element data binding and template

In our application, lists are often used, and the style of the list elements, we hope to be able to customize, according to the MVVM design pattern, our list elements also need to be bound to the background data, so that the background data When updating, the front UI will also be updated, including elements will be added and deleted automatically.

Use ItemsControl

ItemsControl is the most basic "multi-element" control, such as ListBox and ListView, which are based on ItemsControl, because ListBox and ListView have some default styles. For example, ListBox has a scroll bar, so when we customize it, it is still It is recommended to use ItemsControl.

First write a simple data model:

public class StudentInfo
{
    
    
    public string Name {
    
     get; set; }
    public string Description {
    
     get; set; }

    public int Age {
    
     get; set; }
    public string Gender {
    
     get; set; }

    public int Grade {
    
     get; set; }
}

Write another ViewModel for binding data :

public class MainWindowModel
{
    
    
    public ObservableCollection<StudentInfo> StudentInfos {
    
     get; } = new ObservableCollection<StudentInfo>()
    {
    
    
        new StudentInfo()
        {
    
    
            Name = "IFdream",
            Description = "上课不听讲的学生",

            Age = 17,
            Gender = "Female",
            Grade = 114514
        },

        new StudentInfo()
        {
    
    
            Name = "ilyFairy",
            Description = "哼哼哼啊啊啊的学生",

            Age = 21,
            Gender = "武装直升机",
            Grade = 1919810
        }
    };
}

Then write a simple interface in the window:

<Window x:Class="WpfItemsBindingTutorial.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:vm="clr-namespace:WpfItemsBindingTutorial.ViewModels"
        xmlns:local="clr-namespace:WpfItemsBindingTutorial"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
  <Window.DataContext>
    <!--直接给窗体的 DataContext 赋值-->
    <vm:MainWindowModel/>
  </Window.DataContext>
  <Grid>
    <Grid Margin="20" MaxWidth="400">
      <StackPanel>

        <!--使用 ItemsControl 进行集合的数据绑定, 在 ItemsSource 里面指定我们的集合-->
        <ItemsControl ItemsSource="{Binding StudentInfos}">
          <ItemsControl.ItemTemplate>

            <!--使用数据模板就可以为每一个元素自定义呈现方式了-->
            <DataTemplate>

              <!--整一个边框, 加背景颜色, 圆角, 以及内外边距-->
              <Border Margin="0 10 0 0" Padding="5" Background="#eeeeee" CornerRadius="5">

                <!--用 Effect 加个阴影-->
                <Border.Effect>
                  <DropShadowEffect ShadowDepth="0" BlurRadius="3"/>
                </Border.Effect>

                <!--这里用栈布局来做主要内容-->
                <StackPanel>

                  <!--在数据模板中, 可以直接绑定到我们的数据成员-->
                  <TextBlock>
                    <Run Text="Name:"/>
                    <Run Text="{Binding Name}"/>
                  </TextBlock>
                  <TextBlock>
                    <Run Text="Description:"/>
                    <Run Text="{Binding Description}"/>
                  </TextBlock>

                  <!--用 UniformGrid 做个三栏布局-->
                  <UniformGrid Columns="3">
                    <TextBlock>
                      <Run Text="Age:"/>
                      <Run Text="{Binding Age}"/>
                    </TextBlock>
                    <TextBlock>
                      <Run Text="Gender:"/>
                      <Run Text="{Binding Gender}"/>
                    </TextBlock>
                    <TextBlock>
                      <Run Text="Grade:"/>
                      <Run Text="{Binding Grade}"/>
                    </TextBlock>
                  </UniformGrid>
                </StackPanel>
              </Border>
            </DataTemplate>
          </ItemsControl.ItemTemplate>
        </ItemsControl>
      </StackPanel>
    </Grid>
  </Grid>
</Window>

So we got a page like this:
Effect preview

Use ListBox

In fact, ListBoxthe use of and ItemsControlis similar, including the same way of binding ItemsSource, the same way of setting ItemTemplate, but ListBoxrequires users to pay attention to these contents:

  1. ListBoxThe element is selectable, if you don't want the element to be selectable, then useItemsControl
  2. ListBoxIt has its own scroll bar, if you want to control the scroll bar yourself, you can use ScrollViewer.XXXadditional properties to operate on it

ListBoxThe element is selected, which means that this thing is only suitable for the "selection" of some data, for example, I want to fill in a form, and then select a data for the user. If I want to make a chat window, the chat message in the chat window , is obviously a "container", and then each message bubble is an element, which can be completely solved by binding, and using ListBox will make the message selectable, which is not good, I just want him to automatically generate controls, so Use ItemsControl.

However, if you want to use ListBoxto make a "navigation bar" , it is indeed a good choice, because you can directly subscribe SelectionChangedand handle the logic of page jump in the event.

Guess you like

Origin blog.csdn.net/m0_46555380/article/details/129895917