900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > WPF中的自定义控件模板

WPF中的自定义控件模板

时间:2020-08-09 05:08:08

相关推荐

WPF中的自定义控件模板

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

开发工具与关键技术:Visual Studio 、模板

作者:邓崇富

撰写时间: 5 月 24 日

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

在WPF中,通过引入模板(Template)微软将数据和算法的“内容”与“形式”解耦了。WPF中的Template分为两大类:

ControlTemplate是算法内容的表现形式,一个控件怎样组织其内部结构才能让它更符合业务逻辑、让客户操作起来更加舒服就是由它来控制的。他决定了控件“长成什么样子”,并让程序员有机会在控件原有的内部逻辑基础上扩展自己的逻辑。DataTemplate是数据内容的表现形式,一条数据显示成什么样子,是简单的文本还是直观的图形动画就由它来决定。

总而言之,Template就是“外衣”,ControlTemplate是控件的外衣,DataTemplate是数据的外衣。

数据的外衣(DataTemplate):

DataTemplate常用的地方有3个,分别是:

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

下面用个例子来对比UserControl与DataTemplate的使用。假如有一列汽车的数据,这列数据显示在ListBox里,要求ListBox的条目显示汽车的厂商图标和简要的参数,单击某个条目后在窗体的详细内容区域显示汽车的图片和详细参数。

首先要为在项目里建立资源管理目录并把图片添加进来。Logo的文件名与厂商名称要一致,照片的文件名则与车名一致,因为无论是使用UserControl还是DataTemplate,厂商的Logo和汽车的照片都要用到的。

文件结构如下图:

首先创建一个Car数据类型的类文件:

namespace WPF练习

{

public class Car

{

public string Automaker { get; set; }

public string Name { get; set; }

public string Year { get; set; }

public string TopSpeed { get; set; }

}

}

为了在ListBox里显示Car类型数据,我们需要创建一个UserControl,命名为CarListItemView。这个UserControl由一个Car类型实例在背后支持,当设置这个实例的时候,界面元素将实例的属性值显示在各个控件里。CarListItemView的XAML的代码如下:

<UserControl x:Class="WPF练习.CarListItemView"

<!--省略了两个命名空间-->

<Grid Margin="2">

<StackPanel Orientation="Horizontal">

<Image x:Name="ImageLogos" Grid.RowSpan="3" Width="64" Height="64"/>

<StackPanel Margin="5,10">

<TextBlock x:Name="textBlockName" FontSize="16" FontWeight="Bold"/>

<TextBlock x:Name="textBlockYear" FontSize="14"/>

</StackPanel>

</StackPanel>

</Grid>

</UserControl>

CarListItemView界面的后台代码如下:

public partial class CarListItemView : UserControl

{

public CarListItemView()

{

InitializeComponent();

}

private Car car;

public Car Car

{

get { return car; }

set

{

car = value;

this.textBlockName.Text = car.Name;

this.textBlockYear.Text = car.Year;

string uriStr = string.Format(@"/Pitrues/Logos/{0}.PNG", car.Automaker);

this.ImageLogos.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative));

}

}

}

类似于上面的原理,还需要为Car类型数据准备一个详细信息的视图,在创建一个UserControl命名为CarDetailView, XAML代码如下:

<UserControl x:Class="WPF练习.CarDetailView"

<!--此处省略了两个命名空间-->

<Border BorderBrush ="Black" BorderThickness="1" CornerRadius="6">

<StackPanel Margin="5">

<Image x:Name="ImagePhoto" Width="400" Height="250"/>

<StackPanel Orientation="Horizontal" Margin="5,0">

<TextBlock Text="Name:" FontWeight="Bold" FontSize="20"/>

<TextBlock x:Name="textBlockName" FontSize="20" Margin="5,0"/>

</StackPanel>

<StackPanel Orientation="Horizontal" Margin="5,0">

<TextBlock Text="Automaker:" FontWeight="Bold"/>

<TextBlock x:Name="textBlockAutomaker" Margin="5,0"/>

<TextBlock Text="Year:" FontWeight="Bold"/>

<TextBlock x:Name="textBlockYear" Margin="5,0"/>

<TextBlock Text="Top Speed:" FontWeight="Bold"/>

<TextBlock x:Name="textBlockTopSpeed" Margin="5,0"/>

</StackPanel>

</StackPanel>

</Border>

</UserControl>

XAML的后台代码:

public partial class CarDetailView : UserControl

{

public CarDetailView()

{

InitializeComponent();

}

private Car car;

public Car Car

{

get { return car; }

set

{

car = value;

this.textBlockName.Text = car.Name;

this.textBlockYear.Text = car.Year;

this.textBlockTopSpeed.Text = car.TopSpeed;

this.textBlockAutomaker.Text = car.Automaker;

string uriStr = string.Format(@"/Pitrues/Images/{0}.jpg", car.Name);

this.ImagePhoto.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative));

}

}

}

最后把上面两个界面组装到主窗体上,下面是组窗体的XAML代码:

<Window x:Class="WPF练习.Window8"

<!--此处省略里四个命名空间-->

xmlns:local="clr-namespace:WPF练习"

mc:Ignorable="d"

Title="Window8" Height="350" Width="623">

<StackPanel Orientation="Horizontal" Margin="5">

<local:CarDetailView x:Name="detailView"/>

<ListBox x:Name="ListBoxCars" Width="180" Margin="5,0" SelectionChanged="listBoxCars_SelectionChanged"/>

</StackPanel>

</Window>

下面是组窗体的后台代码:

public partial class Window8 : Window

{

public Window8()

{

InitializeComponent();

InitialCarList();

}

private void InitialCarList()

{

List<Car> carList = new List<Car>()

{

new Car(){Automaker = "Lamborghini",Name = "Diablo",Year = "1990",TopSpeed = "340"},

new Car(){Automaker = "Lamborghini",Name = "Murcielago",Year = "2001",TopSpeed = "353"},

new Car(){Automaker = "Lamborghini",Name = "Gallardo",Year = "",TopSpeed = "325"},

new Car(){Automaker = "Lamborghini",Name = "Reventon",Year = "",TopSpeed = "356"}

};

foreach (Car car in carList)

{

CarListItemView view = new CarListItemView();

view.Car = car;

this.ListBoxCars.Items.Add(view);

}

}

//选项变化事件的处理器

private void listBoxCars_SelectionChanged(object sender,SelectionChangedEventArgs e)

{

CarListItemView view = e.AddedItems[0] as CarListItemView;

if (view != null)

{

this.detailView.Car = view.Car;

}

}

}

运行后单击ListBox里的条目,效果图如下:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。