zoukankan      html  css  js  c++  java
  • WPF 基础

    如果把控件的功能视为内容,则可以使用控件模板 ControlTemplate 来控制它的展现;
    如果把数据视为内容,则可以使用数据模板 DataTemplate 把数据展示出来;

    ControlTemplate 是算法内容的表现形式,一个控件怎样组织其内部结构才让它更符合业务逻辑、让用户操作起来更舒服就是由它来控制的;
    DataTemplate 是数据内容的表现形式,一条数据是简单的文本还是图形动画还是其他,由它决定。

    1. DataTemplate

    1.1 一条柱状图的 DataTemplate 举例

    <DataTemplate x:Key="dt">
        <Grid>
            <StackPanel Orientation="Horizontal">
                <Grid>
                    <Rectangle Width="{Binding Price}" Fill="LightSalmon"/>
                    <TextBlock Text="{Binding Year}"></TextBlock>
                </Grid>
                <TextBlock Text="{Binding Price}"></TextBlock>
            </StackPanel>
        </Grid>
    </DataTemplate>
    

    1.2 常用 DataTemplate 的 3 处地方

    ContentControl 的 ContentTemplate 属性,给 ContentControl 的内容穿衣服;
    ItemsControl 的 ItemTemplate 属性,给 ItemsControl 的数据条目穿衣服;
    GridViewColumn 的 CellTemplate 属性,给 GridViewColumn 单元格里的数据穿衣服。

    1.3 使用 DataTemplate 实现一个汽车列表和详情

    <Window x:Class="WpfAppTemplate.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:local="clr-namespace:WpfAppTemplate"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="623">
        <Window.Resources>
            <local:NameToPhotoPathConverter x:Key="nameToPhotoPathConverter"/>
            
            <!--集合条目的内容模板-->
            <DataTemplate x:Key="carListItemViewTemplate">
                <Grid Margin="2">
                    <StackPanel Orientation="Horizontal">
                        <Image Height="60" Width="64" 
                               Source="{Binding Name, Converter={StaticResource nameToPhotoPathConverter}}" />
                        <StackPanel Margin="5 12">
                            <TextBlock Text="Name" FontWeight="Bold"/>
                            <TextBlock Text="{Binding Name}"/>
                        </StackPanel>
                    </StackPanel>
                </Grid>
            </DataTemplate>
    
            <!--详情的内容模板-->
            <DataTemplate x:Key="carDetailViewTemplate">
                <Border BorderBrush="Black" BorderThickness="1" CornerRadius="6" Margin="2">
                    <StackPanel Margin="5">
                        <Image Height="250" Width="400"
                               Source="{Binding Name, Converter={StaticResource nameToPhotoPathConverter}}" />
                        <StackPanel Orientation="Horizontal" Margin="5,0">
                            <TextBlock Text="Name:" FontWeight="Bold" FontSize="19"/>
                            <TextBlock Text="{Binding Name}" FontSize="19"/>
                        </StackPanel>
                        <StackPanel Orientation="Horizontal" Margin="5 0">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="Year:" FontWeight="Bold"/>
                                <TextBlock Text="{Binding Year}"/>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" Margin="5 0">
                                <TextBlock Text="TopSpeed:" FontWeight="Bold"/>
                                <TextBlock Text="{Binding TopSpeed}"/>
                            </StackPanel>
                        </StackPanel>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </Window.Resources>
        
        <Grid>        
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="5*"/>
                <ColumnDefinition Width="2*"/>
            </Grid.ColumnDefinitions>
    
            <UserControl x:Name="carDetailControl" 
                         ContentTemplate="{StaticResource carDetailViewTemplate}" 
                         Content="{Binding ElementName=listBoxCar, Path=SelectedItem}" />
    
            <ListBox Grid.Column="1" x:Name="listBoxCar" Margin="2" 
                     ItemTemplate="{StaticResource carListItemViewTemplate}" />   
        </Grid>
    </Window>
    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InitializeList();
        }
    
        /// <summary>
        /// 添加汽车种类
        /// </summary>
        void InitializeList()
        {
            List<Car> carList = new List<Car>();
            carList.Add(new Car() { Name = "BMW", TopSpeed = "260", Year = "1997" });
            carList.Add(new Car() { Name = "Audi", TopSpeed = "240", Year = "1999" });
            carList.Add(new Car() { Name = "Toyota", TopSpeed = "120", Year = "2016" });
            carList.Add(new Car() { Name = "Volkswagen", TopSpeed = "150", Year = "2000" });
    
            this.listBoxCar.ItemsSource = carList;
        }
     }
    

    1.4 而如果不用 DataTemplate ,就会显得比较繁琐且冗长

    使用 winform 的 Usercontrol 实现一个汽车列表和详情

    <!--汽车详情-->
    <UserControl x:Class="WpfAppTemplate.UserControls.CarDetailUserControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfAppTemplate.UserControls"
                 mc:Ignorable="d" >
        <Border BorderBrush="Black" BorderThickness="1" CornerRadius="6" Margin="2"> 
            <StackPanel Margin="5">
                <Image x:Name="img" Height="250" Width="400"/>
    
                <StackPanel Orientation="Horizontal" Margin="5,0">
                    <TextBlock Text="Name:" FontWeight="Bold" FontSize="19"/>
                    <TextBlock x:Name="textBlockName" FontSize="19"/>
                </StackPanel>
    
                <StackPanel Orientation="Horizontal" Margin="5 0">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="Year:" FontWeight="Bold"/>
                        <TextBlock x:Name="textBlockYear"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Margin="5 0">
                        <TextBlock Text="TopSpeed:" FontWeight="Bold"/>
                        <TextBlock x:Name="textBlockTopSpeed"/>
                    </StackPanel> 
                </StackPanel>
                
            </StackPanel>
        </Border>
    </UserControl>
    
    public partial class CarDetailUserControl : UserControl
    {
        public CarDetailUserControl()
        {
            InitializeComponent();
        }
    
        Car _currentCar;
        public Car CurrentCar
        {
            get { return _currentCar; }
            set
            {
                if (value == null) return;
                _currentCar = value;
                this.textBlockName.Text = value.Name;
                this.textBlockTopSpeed.Text = value.TopSpeed;
                this.textBlockYear.Text = value.Year;
                string uriStr = string.Format(@"/Resources/Images/Cars/{0}.jpg", value.Name);
                this.img.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative));
            }
        }        
    }
    
    <!--汽车条目-->
    <UserControl x:Class="WpfAppTemplate.UserControls.CarListItemUserControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfAppTemplate.UserControls"
                 mc:Ignorable="d">
        <Grid Margin="2">
            <StackPanel Orientation="Horizontal">
                <Image x:Name="img" Height="60" Width="64"/>
                <StackPanel Margin="5 12">
                    <TextBlock Text="Name" FontWeight="Bold"/>
                    <TextBlock x:Name="textBlockName" />
                </StackPanel>
            </StackPanel>
        </Grid>
    </UserControl>
    
    public partial class CarListItemUserControl : UserControl
    {
        public CarListItemUserControl()
        {
            InitializeComponent();
        }
    
        Car _currentCar;
        public Car CurrentCar
        {
            get { return _currentCar; }
            set
            {
                if (value == null) return;
    
                _currentCar = value;
                this.textBlockName.Text = value.Name;
                string uriStr = string.Format(@"/Resources/Images/Cars/{0}.jpg", value.Name);
                this.img.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative));
            }
        }
    }
    
    <!--主窗体-->
    <Window x:Class="WpfAppTemplate.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:local="clr-namespace:WpfAppTemplate"
            xmlns:localUserControls="clr-namespace:WpfAppTemplate.UserControls"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="623">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="5*"/>
                <ColumnDefinition Width="2*"/>
            </Grid.ColumnDefinitions>
    
            <localUserControls:CarDetailUserControl x:Name="carDetailControl"/>
    
            <ListBox Grid.Column="1" x:Name="listBoxCar" SelectionChanged="listBoxCar_SelectionChanged" Margin="2"/>
        </Grid>
    </Window>
    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InitializeList();
        }
    
        /// <summary>
        /// 添加汽车种类
        /// </summary>
        void InitializeList()
        {
            List<Car> carList = new List<Car>();
            carList.Add(new Car() { Name = "BMW", TopSpeed = "260", Year = "1997" });
            carList.Add(new Car() { Name = "Audi", TopSpeed = "240", Year = "1999" });
            carList.Add(new Car() { Name = "Toyota", TopSpeed = "120", Year = "2016" });
            carList.Add(new Car() { Name = "Volkswagen", TopSpeed = "150", Year = "2000" });
    
            // 给每种汽车生成一个 汽车条目控件,作为一条内容添加到汽车列表控件的内容集合
            foreach (Car car in carList)
            {
                CarListItemUserControl control = new CarListItemUserControl();
                control.CurrentCar = car;
                this.listBoxCar.Items.Add(control);
            }
        }
    
        /// <summary>
        /// 当切换汽车时
        /// </summary>
        /// <param name="sender">listbox</param>
        /// <param name="e">SelectionChangedEventArgs, 可以通过 AddedItems 参数取到新选择的项</param>
        private void listBoxCar_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            CarListItemUserControl control = e.AddedItems[0] as CarListItemUserControl;
            if (control != null)
            {
                this.carDetailControl.CurrentCar = control.CurrentCar;
            }
        }
    }
    
  • 相关阅读:
    S MVC 转发与重定向
    S MVC Controller方法返回值
    S MVC 表单提交
    numpy数据平滑
    Python入门
    Django
    python机器学习基础教程-监督学习
    drf-CBV
    numpy数组符号化与函数向量化
    numpy中多项式拟合与复数
  • 原文地址:https://www.cnblogs.com/MichaelLoveSna/p/14447919.html
Copyright © 2011-2022 走看看