WPF的数据绑定详细介绍

一、WPF数据绑定的概要

数据绑定:是应用程序 UI 与业务逻辑之间建立连接的过程。 如果绑定正确设置并且数据提供正确通知,则当数据的值发生更改时,绑定到数据的视觉元素会自动反映更改。 数据绑定可能还意味着如果视觉元素中数据的外部表现形式发生更改,则基础数据可以自动更新以反映更改。

例如:如果用户编辑 TextBox 元素中的值,则基础数据值会自动更新以反映该更改。

1. 数据绑定涉及到两个方面:

一个是绑定源,一个是绑定目标。绑定源即控件绑定所使用的源数据,绑定目标即数据显示的控件。

2. 对于绑定源,在WPF可以是以下四种:

•CLR对象:可以绑定到CLR类的公开的属性、子属性、索引器上。
•ADO.Net对象:例如DataTable、DataView等 。
•XML文件:使用XPath进行解析 。
•DependencyObject:绑定到其依赖项属性上,即控件绑定控件 。
对于绑定目标,必须是WPF中的DependencyObject,将数据绑定到其依赖项属性上。

二、      绑定的模式

1.  根据数据流的方向,WPF中的数据绑定分为以下四种:

OneWay 绑定:对源属性的更改会自动更新目标属性,但是对目标属性的更改不会传播回源属性。此绑定类型适用于绑定的控件为隐式只读控件的情况。

TwoWay 绑定:对源属性的更改会自动更新目标属性,而对目标属性的更改也会自动更新源属性。此绑定类型适用于可编辑窗体或其他完全交互式 UI 方案 。

OneWayToSource 与 OneWay 相反;它在目标属性更改时更新源属性。

OneTime绑定:该绑定会导致源属性初始化目标属性,但不传播后续更改。

注释:如果无需监视目标属性的更改,则使用 OneWay 绑定模式可避免 TwoWay 绑定模式的系统开销。

大多数属性都默认为 OneWay 绑定,但是一些依赖项属性,通常为用户可编辑的控件的属性,如 TextBox 的 Text 属性和 CheckBox 的 IsChecked 属性,默认为 TwoWay 绑定。

如果要知道依赖项属性绑定在默认情况下是单向还是双向的编程方法可使用 GetMetadata 获取属性的属性元数据,然后检查 BindsTwoWayByDefault 属性的布尔值。

示例代码:

代码如下:

<Page x:Class="WpfDemo.Page1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Page1" HorizontalAlignment="Center">

<Grid Name="GridTable" Height="360" Background="Silver">

<Grid.RowDefinitions>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="130"></ColumnDefinition>

<ColumnDefinition Width="150"></ColumnDefinition>

<ColumnDefinition Width="20"></ColumnDefinition>

</Grid.ColumnDefinitions>

<Label Width="130" Height="25"  Grid.Row="0" Grid.Column="0"  Name="label1">TwoWay</Label>

<TextBox Width="150" Height="25"  Grid.Row="0" Grid.Column="1"  Name="textBox4" Text="{Binding ElementName=scrollBar1,Path=Value,Mode=TwoWay}" />

<Label Width="130" Height="25"  Grid.Row="1" Grid.Column="0"  Name="label2">OneWay</Label>

<TextBox Width="150" Height="25"  Grid.Row="1" Grid.Column="1"   Name="textBox1" Text="{Binding ElementName=scrollBar1, Path=Value,Mode=OneWay}"/>

<Label Width="130" Height="25"  Grid.Row="2" Grid.Column="0"  Name="label3">OneWayToSource</Label>

<TextBox Width="150" Height="25"  Grid.Row="2" Grid.Column="1"   Name="textBox2" Text="{Binding ElementName=scrollBar1, Path=Value,Mode=OneWayToSource}" />

<Label Width="130" Height="25"  Grid.Row="3" Grid.Column="0"  Name="label4">OneTime</Label>

<TextBox Width="150" Height="25"  Grid.Row="3" Grid.Column="1"   Name="textBox3" Text="{Binding ElementName=scrollBar1, Path=Value,Mode=OneTime}"/>

<ScrollBar Value="30" Minimum="0" Grid.RowSpan="4" Grid.Row="0" Grid.Column="2" Maximum="100" Name="scrollBar1" Width="18" Height="{Binding ElementName=GridTable,Path=Height}" />

</Grid>

</Page>

根据程序执行结果,我们可以得到以下结论:

对于OneWay绑定:在界面中显示的数据可以随数据源的值的变化而变化,但更改界面的数据不会影响到数据源。

对于TwoWay绑定:界面中显示的数据及数据源的数据可以双向显示及更新。

对于OneWayToSource绑定:初始时界面的数据为空;更改界面的数据可以影响数据源的值,但是更改数据源的值不会体现在界面上。

对于OneTime绑定:在界面中显示的为数据源的初始值,更改数据源的值的时候,不会更改界面的数据显示;更改界面的数据也不会影响到数据源的数据。

三、绑定目标值影响绑定源值条件

问题:绑定源的值是在您编辑文本的同时进行更新,还是在您结束编辑文本并将鼠标指针从文本框移走后才进行更新呢?或者在您需要更新的情况下在手动的更新呢?

1. UpdateSourceTrigger 属性是确定触发源更新的原因。

下图中右箭头的点演示 UpdateSourceTrigger 属性的角色:

TwoWay及OneWayToSource是由绑定目标到绑定源方向,若实现绑定目标的值更改影响绑定源的值方式,只需要设置相应控件绑定时的UpdateSourceTrigger的值,其值有三种:

PropertyChanged:当绑定目标属性更改时,立即更新绑定源。

LostFocus:当绑定目标元素失去焦点时,更新绑定源。

Explicit:仅在调用 UpdateSource 方法时更新绑定源。

注释:多数依赖项属性的UpdateSourceTrigger 值的默认值为 PropertyChanged,而 Text 属性的默认值为 LostFocus。

2. 示例

代码如下:

XAML:

<Page x:Class="WpfDemo.Changed"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Changed">

<Grid Name="GridTable" Height="250" Background="Silver" Width="350">

<Grid.RowDefinitions>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="100"></ColumnDefinition>

<ColumnDefinition Width="150"></ColumnDefinition>

<ColumnDefinition Width="100"></ColumnDefinition>

</Grid.ColumnDefinitions>

<TextBlock Grid.Row="0" Width="90" Height="25" Grid.Column="0" Name="label1" Text="PropertyChanged:"></TextBlock>

<TextBlock Grid.Row="1"  Width="90" Height="25" Grid.Column="0" Name="label2" Text="LostFocus:"></TextBlock>

<TextBlock Grid.Row="2"  Width="90" Height="25" Grid.Column="0" Name="label3" Text="Explicit:"></TextBlock>

<TextBox Grid.Row="0" Width="150" Height="25" Text="{Binding Path=UserName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  Grid.Column="1" Name="TextBox1" />

<TextBox Grid.Row="1" Width="150" Height="25" Text="{Binding Path=UserName,Mode=TwoWay,UpdateSourceTrigger=LostFocus}"   Grid.Column="1"  Name="TextBox2" />

<TextBox Grid.Row="2" Width="150" Height="25" Text="{Binding Path=UserName,Mode=TwoWay,UpdateSourceTrigger=Explicit}"   Grid.Column="1"  Name="txtExplicit" />

<TextBlock Grid.Row="3" Width="90" Height="25"  Grid.Column="0" Name="lblResult" Text="结果:"></TextBlock>

<TextBlock Grid.Row="3" Width="90" Height="25"  Grid.Column="1" Name="lblDisplay" Text="{Binding Path=UserName,Mode=OneWay}"></TextBlock>

<Button Name="btnChanged" Width="90" Height="25" Grid.Row="3" Grid.Column="2">Explicit</Button>

</Grid>

</Page>

代码如下:

C#:

namespace WpfDemo

{

public partial class Changed : Page

{

#region properties

public UserModel CurrentUser

{

get;set;

}

#endregion

#region Constructor

public Changed()

{

InitializeComponent();

this.Loaded += new RoutedEventHandler(Changed_Loaded);

this.btnChanged.Click += new RoutedEventHandler(btnChanged_Click);

}

#endregion

#region Changed_Loaded

void Changed_Loaded(object sender, RoutedEventArgs e)

{

this.CurrentUser = new UserModel() {UserName="swd"};

this.DataContext = this.CurrentUser;

}

#endregion

#region btnLogon_Click

void btnChanged_Click(object sender, RoutedEventArgs e)

{

this.txtExplicit.GetBindingExpression(TextBox.TextProperty).UpdateSource();

}

#endregion

}

public class UserModel

{

public string UserName

{

get;set;}

}

}

程序执行结果如上所述。

四、      数据提供程序

1. XmlDataProvider:

XmlDataProvider访问 XML 数据的方式有以下三种:

可以使用 XmlDataProvider 类嵌入内联 XML 数据。

可以将 Source 属性设置为 XML 数据文件的 Uri。

可以将 Document 属性设置为 XmlDocument。

注释:当 XmlDocument.NodeChanged 事件发生时,XmlDataProvider 执行所有绑定的完全刷新。 特定节点不进行优化。

默认情况下,XmlDataProvider.IsAsynchronous 属性设置为 true,表示默认情况下 XmlDataProvider 检索数据并异步生成 XML 节点的集合。

以下将介绍使用上面所述的三种方式显示xml数据:

示例

代码如下:

Xaml:

<Page x:Class="WpfDemo.xmlBinding"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="xmlBinding" xmlns:local="clr-namespace:WpfDemo">

<Page.Resources>

<XmlDataProvider x:Key="XmlFile" Source="Students.xml" XPath="/Students"></XmlDataProvider>

<XmlDataProvider x:Key="InnerXmlStu" XPath="/Students">

<x:XData>

<Students xmlns="">

<Student><name>swd</name></Student>

<Student><name>awd</name></Student>

<Student><name>asd</name></Student>

</Students>

</x:XData>

</XmlDataProvider>

</Page.Resources>

<Grid>

<Grid.RowDefinitions>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="100"></ColumnDefinition>

<ColumnDefinition Width="150"></ColumnDefinition>

</Grid.ColumnDefinitions>

<TextBlock Grid.Row="0" Grid.Column="0"  Height="25" Width="100"  Text="引用XML文件"></TextBlock>

<TextBlock Grid.Row="1" Grid.Column="0" Height="25" Width="100"   Text="内嵌XML"></TextBlock>

<TextBlock Grid.Row="2" Grid.Column="0"  Height="25" Width="100"  Text="动态XML"></TextBlock>

<ListBox Name="lisbXmlFile" Grid.Row="0" Grid.Column="1" Height="100" Width="150" ItemsSource="{Binding Source={StaticResource XmlFile},XPath=Student/name}">

</ListBox>

<ListBox Name="lisbInnerXml" Grid.Row="1" Grid.Column="1"  Height="100" Width="150" ItemsSource="{Binding Source={StaticResource InnerXmlStu},XPath=Student/name}">

</ListBox>

<ListBox Name="lisbXmlDoc" Grid.Row="2" Grid.Column="1"  Height="100"  Width="150" ItemsSource="{Binding XPath=Student/name}">

</ListBox>

</Grid>

</Page>

代码如下:

XML:

<?xml version="1.0" encoding="utf-8" ?>

<Students>

<Student>

<name>swd</name>

<score>110</score>

</Student>

<Student>

<name>asd</name>

<score>120</score>

</Student>

<Student>

<name>awd</name>

<score>130</score>

</Student>

</Students>

通过以上示例我想大家应该很容易理解与应用。

2. ObjectDataProvider:

ObjectDataProvider 使您能够在 XAML 中创建可用作绑定源的对象,并为您提供以下属性,以对对象执行查询并绑定到结果。

使用 ConstructorParameters 属性将参数传递给对象的构造函数。

使用 MethodName 属性调用一个方法。

使用 MethodParameters 属性将参数传递给该方法。 然后,可以绑定到该方法的结果。

使用ObjectType 指定将提供数据绑定源的对象。

使用 ObjectInstance 属性来指定现有的对象实例作为源

注释:还可以使用 IsAsynchronous 属性指定是在辅助线程还是在活动上下文中执行对象创建。也就是是否异步检索数据。

示例:

代码如下:

XAML:

C#:

namespace WpfDemo

{

#region CObjectDataProvider

public partial class CObjectDataProvider : Page

{

public CObjectDataProvider()

{InitializeComponent();}

}

#endregion

#region Country

public class Country

{

#region Name

public string Name

{get;set;}

#endregion

#region ProvinceList

public List<Province> ProvinceList

{get;set;}

#endregion

#region GetAllCity

public static List<Country> GetAllCity()

{

return new List<Country>{

new Country

{

Name = "中国",

ProvinceList = new List<Province>

{

new Province{ Name="福建省",

CityList=new List<City>{new City{Name="福州市"},new City{Name="厦门市"},new City{Name="漳州市"},new City{Name="泉州市"}}

},

new Province{Name="江苏省",

CityList=new List<City>{

new City{Name="苏州市"},new City{Name="南京市"},new City{Name="扬州市"},new City{Name="无锡市"}}

},

new Province{Name="江西省",

CityList=new List<City>{new City{Name="南昌市"},new City{Name="九江市"}}}}

}

};

}

#endregion

}

#endregion

#region Province

public class Province

{

#region Name

public string Name

{get;set;}

#endregion

#region CityList

public List<City> CityList

{get;set;}

#endregion

}

#endregion

#region City

public class City

{

#region Name

public string Name

{get;set;}

#endregion

}

#endregion

}

五、类型转换与数据校验

1. IValueConverter接口

提供一种将自定义逻辑应用于绑定的方式。

在Binding时,数据源对象到目标对象之间(或者目标对象到数据源对象)可能需要某种转换。这时只需实现IValueConverter接口自定义值转换器即可。

接口原型定义:

public interface IValueConverter
{
    object Convert(object value, Type targetType, object parameter, CultureInfo culture);
    object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}

参数value是要转换的值,typeTarget是转换后的值类型,parameter是Binding 类的 ConverterParameter传递过来的参数。

Convert方法:数据绑定引擎在将值从绑定源传播给绑定目标时,调用此方法。

ConvertBack方法:数据绑定引擎在将值从绑定目标传播给绑定源时,调用此方法。

ValueConversion属性作用是告诉自定义转换器类可以转换的源数据和目标数据的 类型(ValueConversion属性将在稍后的示例中看到)。

2. ValidationRule类

提供一种为检查用户输入的有效性而创建自定义规则的方法。

ValidationRule : 所有自定义验证规则的基类。提供了让用户定义验证规则的入口。

ExceptionValidation :表示一个规则,该规则检查在绑定源属性更新过程中引发的异常。它是一个内置的规则,它检查在绑定源属性更新过程中引发的异常。

ValidationResult : 数据验证结果的表现方式。ValidationRule对象的Validate方法执行完毕后通过ValidationResult来表示验证的结果。这里包含了错误信息—ErrorContent,数据是否有效—IsValid。ValidResult 为 ValidationResult 的有效实例。

ValidationError :表示一个验证错误,该错误在 ValidationRule 报告验证错误时由绑定引擎创建。

代码如下:

XAML:

<Page x:Class="WpfDemo.TypeConvertAndValidationRule"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="TypeConvertAndValidationRule"

xmlns:src="clr-namespace:WpfDemo">

<Grid Height="250" Width="360" Background="Silver">

<Grid.RowDefinitions>
    <RowDefinition>
    </RowDefinition>
    <RowDefinition>
    </RowDefinition>
    <RowDefinition>
    </RowDefinition>
       </Grid.RowDefinitions>

<Grid.ColumnDefinitions>
               <ColumnDefinition>
    </ColumnDefinition>
    <ColumnDefinition>
    </ColumnDefinition>
        </Grid.ColumnDefinitions>

<TextBlock Height="25" Width="100" Text="生日"  Grid.Row="0" Grid.Column="0"></TextBlock>

<TextBox Name="txtBirthday" Height="25" Width="150"  Grid.Row="0" Grid.Column="1">

<TextBox.Text>

<Binding Path="Birthday" UpdateSourceTrigger="LostFocus" Mode="TwoWay">

<Binding.ValidationRules><src:ValidationDateTimeRule/></Binding.ValidationRules>

<Binding.Converter><src:MyConverterOfBirthFormat/></Binding.Converter>

</Binding>
           </TextBox.Text>

<TextBox.ToolTip>
                <Binding RelativeSource="{RelativeSource Self}" Path="(Validation.Errors)        [0].ErrorContent"></Binding>
           </TextBox.ToolTip>       </TextBox>

<TextBlock Height="25" Width="150" Grid.Row="1" Text="{Binding Path=Birthday,Mode=OneWay}" Grid.Column="1"></TextBlock>

<TextBlock Height="25" Width="100" Text="电子邮件格式检查" Grid.Row="2" Grid.Column="0"></TextBlock>

<TextBox Height="25" Width="150" Grid.Row="2" Grid.Column="1">

<TextBox.Text>

<Binding Path="EMail">

<Binding.ValidationRules><ExceptionValidationRule /></Binding.ValidationRules>

</Binding>            </TextBox.Text>

<TextBox.ToolTip>

<Binding RelativeSource="{RelativeSource Self}" Path="(Validation.Errors)[0].ErrorContent"></Binding>

</TextBox.ToolTip>       </TextBox>

</Grid>

</Page>

代码如下:

C#:

namespace WpfDemo

{

#region TypeConvertAndValidationRule

public partial class TypeConvertAndValidationRule : Page

{

public TypeConvertAndValidationRule()

{

InitializeComponent();

this.DataContext = new UserInfo { Name = "swd", Birthday =System.Convert.ToDateTime("1987/10/21"), EMail = "swd@126.com" };

}

}

#endregion

#region UserInfo

public class UserInfo

{

#region Name

public string Name

{get;set;}

#endregion

#region Birthday

public DateTime Birthday

{get;set;}

#endregion

#region EMail

private string email;

public string EMail

{

get

{return email;}

set

{

this.email = value;

Regex r = new Regex(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");

if (!r.IsMatch(value))

{

throw new ApplicationException("电子邮件格式有误!");

}

}

}

#endregion

}

#endregion

六、      绑定集合对象

1.       ICollectionView接口

允许集合具有当前记录管理、自定义排序、筛选和分组这些功能。比如排序,分组,筛选,导航以及其它自定义视图,并且这不会影响到你的后台数据的实际存储。

2.       ObservableCollection <T> 类

表示一个动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知。

3.       WPF MVVM概要

MVVM(Model-View-ViewModel)是由MVC,MVP演变而来。MVVM分离了逻辑与界面,解放业务逻辑。

(0)

相关推荐

  • 在Winform和WPF中注册全局快捷键实现思路及代码

    快捷键辅助类 复制代码 代码如下: class HotKey { /// <summary> /// 如果函数执行成功,返回值不为0. /// 如果函数执行失败,返回值为0.要得到扩展错误信息,调用GetLastError..NET方法:Marshal.GetLastWin32Error() /// </summary> /// <param name="hWnd">要定义热键的窗口的句柄</param> /// <param na

  • WPF绑定实例详解

    本文详细讲述了WPF绑定的用法,分享给大家供大家参考.具体用法分析如下: 1.WPF绑定使用的源属性必须是依赖项属性,这是因为依赖项属性具有内置的更改通知支持,元素绑定表达式使用了Xaml扩展标记,WPF绑定一个控件是使用Binding.ElementName,绑定非控件对象时使用Source,RelativeSource,DataContext属性(WPF特有,而非XAML),只能绑定对象的共有字段. 下边是部分Binding 属性名,完整列表参考 :http://msdn.microsoft

  • 仿vs实现WPF好看的进度条

    为了界面友好,一般的操作时间较长时,都需要增加进度条提示.由于WPF自带的进度条其实不怎么好看,而且没啥视觉效果.后来,装VS2012时,发现安装过程中进度条效果不错,于是上网查了资料.学习了ModernUI(开源的),地址:https://github.com/firstfloorsoftware/mui. 后来,做了尝试写了个Demo,效果不错.另外,专门录制了tif文件,方便大家看到效果.废话不多说,先展示效果: 一.效果展示 A.VS2012安装界面图: B.个人尝试Demo效果图: 二

  • WPF字体或内容模糊的解决方法

    本文会给大家介绍尝试过的一些方法,大家可以一起看看. 1.用WPF4.0中的新字体渲染方法,没有改善 <Setter Property="TextOptions.TextFormattingMode" Value="Display" /> <Setter Property="TextOptions.TextRenderingMode" Value="ClearType" /> 2.给控件加上SnapsT

  • 关于WPF异步MVVM等待窗体的介绍

    需求描述•在ViewModel中处理Model中的数据需要一定时间的等待•ViewModel或Model在获取数据或访问同步服务时有一定延迟需要等待•ViewModel操作View加载数据需要一段时间解决办法•显示一个等待UI,当数据处理完毕或服务接口返回后等待UI消失转动齿轮控件•参考开源实现SprocketControl :http://wpfspark.codeplex.com/等待控件 复制代码 代码如下: <Grid>     <local:SprocketControl Gr

  • 关于.NET/C#/WCF/WPF 打造IP网络智能视频监控系统的介绍

    OptimalVision网络视频监控系统 OptimalVision(OV)网络视频监控系统(Video Surveillance System),是一套基于.NET.C#.WCF.WPF等技术构建的IP网络视频监控系统.设计与实现该系统的初衷是希望在家用电脑中部署该系统,连接本地或局域网设备,通过浏览器或手机客户端浏览宝宝实时视频,也就是俗称的"宝宝在线"或"家庭看护". 但由于业余时间总是有限,完成系统中的服务.配置.采集.传输和桌面GUI部分后,继续完成后续

  • WPF实现渐变淡入淡出的登陆窗口效果

    本文实例讲述了WPF实现渐变淡入淡出的登陆窗口效果的方法.分享给大家供大家参考.具体实现方法如下: 1.实现原理 ① 利用UIElement.OpacityMask属性,用于改变对象区域的不透明度的画笔.可以使元素的特定区域透明或部分透明,从而实现比较新颖的效果. ② OpacityMask属性接受任何画刷,可利用LinearGradientBrush线性渐变画刷,通过对渐变画刷中各颜色点加以动画处理即可. 2.渐变淡入实现 渐变淡入效果,可通过事件触发器触发Loaded事件实现,所以可以仅用前

  • wpf将表中数据显示到datagrid示例

    a.在.xaml文件中拖入一个datagrid,然后添加列名,使用Binding="{Binding 数据库中的列名称}",如下:  复制代码 代码如下: <DataGrid AutoGenerateColumns="False" Height="438"HorizontalAlignment="Left" Margin="23,278,0,0" Name="dataGrid1" 

  • 在WinForm和WPF中使用GMap.Net地图插件简单教程

    如何在WinForm中使用GMap.Net 项目主页:https://greatmaps.codeplex.com/ 下载GMap.Net,我下载的版本:greatmaps_81b71bf30091,编译三个核心项目: GMap.Net.Core:核心DLL GMap.Net.WindowsForms:WinForm中使用的DLL GMap.NET.WindowsPresentation:WPF中使用的DLL 在WinForm项目中使用GMap: 1.新建一个Visual C# 的Windows

  • WPF制作一个简单的倒计时器实例附源码

    实例一: 早上起来后闲的无事,于是想到前些日子学院的某个老师让大家给他找个什么倒计时的小软件,当时大家忙于复习所以也懒得搭理这件事,囧~.既然早上没事干,何不写个玩玩~既然要写,就用以前没怎么捣鼓过的WPF写一个吧,也算是一次学习WPF的初探吧(感觉自己很落后了)! 在Vs2008和Vs2010之间徘徊了许久之后,最终还是选择了Vs2008做开发IDE.在Vs2008中建了个WPF工程后,浏览了下默认生成的工程文件结构,一个App.xaml(当然还有App.xaml.cs)和一个Windows1

随机推荐