8天入门wpf—— 第八天 最后的补充

从这一篇往前看,其实wpf中还有很多东西没有讲到,不过我的原则还是将比较常用的知识点过一遍,如果大家熟悉了这些知识,基本功

也就打的差不多了,后续可以等待老邓的wpf细说系列,这里我先顶老邓一下。

一:用户控件(UserControl)

对于用户控件的认识,我想大家还是很熟悉的,因为这玩意我们在webform或者在mvc中用的可多了,我们看看wpf中怎么使用,首先

我们要知道"用户控件“继承自UserControl,而UserControl继承自ContentControl,也就是上上一篇说的”内容控件”。

第一步:在vs中的添加项中找到一个“用户控件WPF”,点击添加即可。


第二步:我们发现其实UserControl和Window是一个层次上的,都有xaml和cs文件,然后我们在xaml中拖几个控件。

<UserControl x:Class="WpfApplication8.AddProduct"
 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"
 mc:Ignorable="d"
 d:DesignHeight="200" d:DesignWidth="300">
 <Grid Height="171" Width="262">
 <TextBlock Height="20" HorizontalAlignment="Left" Margin="28,57,0,0" Name="textBlock1" Text="名称:" VerticalAlignment="Top" Width="42" />
 <TextBlock Height="20" HorizontalAlignment="Left" Margin="28,92,0,0" Name="textBlock2" Text="价格:" VerticalAlignment="Top" Width="42" />
 <TextBox Height="23" HorizontalAlignment="Left" Margin="76,54,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
 <TextBox Height="23" HorizontalAlignment="Left" Margin="76,92,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" />
 </Grid>
</UserControl>


第三步:我们在MainWindow中引用,跟webform中使用套路一模一样,最后也就ok了。

<Window x:Class="WpfApplication8.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:WpfApplication8"
 Title="MainWindow" Height="350" Width="525">
 <Grid>
 <local:AddProduct x:Name="test"/>
 </Grid>
</Window>


二:资源文件

先前文章我也说过,资源就类似于webform中的css,但是实际应用中,css都是一个个单独的文件来实现内容与样式的分离,当然

wpf中也主张这么做。

第一步:vs中新建项 -> 资源字典->点击确定


第二步:这里我就将默认生成的Dictionary1.xaml放在解决方案的Style文件夹下,然后我们写上一段简单的style。

1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
3 <Style x:Key="backColor" TargetType="{x:Type Button}">
4 <Setter Property="Background" Value="Red"/>
5 </Style>
6 </ResourceDictionary>

第三步:在Resources上引用,指定资源文件路径,跟webform中的css文件引用一样一样的。

<Window x:Class="WpfApplication9.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
 <!-- 引用外部资源文件 -->
 <ResourceDictionary>
 <ResourceDictionary.MergedDictionaries>
 <ResourceDictionary Source="/Style/Dictionary1.xaml"/>
 </ResourceDictionary.MergedDictionaries>
 </ResourceDictionary>
 </Window.Resources>
 <Grid>
 <Button Content="Button" Style="{StaticResource ResourceKey=backColor}" Height="23" HorizontalAlignment="Left" Margin="104,58,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
 </Grid>
</Window>


三:了解wpf中Window的生命周期

了解生命周期,可以让我们更好的控制生命周期内各个阶段发生的行为,具体怎么灵活运用,得要看大家灵活发挥了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;

namespace WpfApplication10
{
 /// <summary>
 /// MainWindow.xaml 的交互逻辑
 /// </summary>
 public partial class MainWindow : Window
 {
 public MainWindow()
 {
 InitializeComponent();

 //初始化
 this.Initialized += (sender, e) =>
 {
 Debug.WriteLine("窗体初始化完成 Initialized");
 };

 //激活
 this.Activated += (sender, e) =>
 {
 Debug.WriteLine("窗体被激活 Activated");
 };

 //加载
 this.Loaded += (sender, e) =>
 {
 Debug.WriteLine("窗体加载完成 Loaded");
 };

 //呈现内容
 this.ContentRendered += (sender, e) =>
 {
 Debug.WriteLine("呈现内容 ContentRendered");
 };

 //失活
 this.Deactivated += (sender, e) =>
 {
 Debug.WriteLine("窗体被失活 Deactivated");
 };

 //窗体获取输入焦点
 this.GotFocus += (sender, e) =>
 {
 Debug.WriteLine("窗体获取输入焦点 GotFocus");
 };

 //窗体失去输入焦点
 this.LostFocus += (sender, e) =>
 {
 Debug.WriteLine("窗体失去输入焦点 LostFocus");
 };

 //键盘获取输入焦点
 this.GotKeyboardFocus += (sender, e) =>
 {
 Debug.WriteLine("键盘获取输入焦点 GotKeyboardFocus");
 };

 //键盘失去输入焦点
 this.LostKeyboardFocus += (sender, e) =>
 {
 Debug.WriteLine("键盘失去输入焦点 LostKeyboardFocus");
 };

 //正在关闭
 this.Closing += (sender, e) =>
 {
 Debug.WriteLine("窗体正在关闭 Closeing");
 };

 //关闭
 this.Closed += (sender, e) =>
 {
 Debug.WriteLine("窗体正在关闭 Closed");
 };

 }
 }
}

从窗体的开启到关闭,我们可以在“输出窗口”中看到如下的事件发生顺序流。


四:属性更改通知(INotifyPropertyChanged)

我们在开发webform中,如果删除GridView里面的一行,我们的作法肯定就是在数据库中删除掉选定的记录然后重新绑定GridView控件

来实现我们的需求,注意,这里有“重新绑定”一词,但是在wpf中有一个突破,前一篇文章我也提到过wpf中的ObservableCollection<T>,

MSDN中说,在添加项,移除项时此集合通知控件,我们知道对一个集合的操作是CURD,但是恰恰没有Update的时候提供集合通知,也就

是说当我Update的时候,虽然"集合内容“已被修改,但是"控件“却没有实现同步更新,怎么办呢?INotifyPropertyChanged提供了解决方案。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Windows.Controls.Primitives;
using System.ComponentModel;

namespace ListViewDemo
{
 /// <summary>
 /// MainWindow.xaml 的交互逻辑
 /// </summary>
 public partial class MainWindow : Window
 {
 private ObservableCollection<Person> personList = new ObservableCollection<Person>();

 public MainWindow()
 {
 InitializeComponent();

 personList.Add(new Person() { Name = "一线码农", Age = 24 });

 personList.Add(new Person() { Name = "XXX", Age = 21 });

 listview1.ItemsSource = personList;
 }

 private void Button_Click(object sender, RoutedEventArgs e)
 {
 var first = personList.FirstOrDefault();

 first.Name = textBox1.Text;
 }
 }

 public class Person : INotifyPropertyChanged
 {
 public string name;

 public string Name
 {
 get
 {
 return name;
 }
 set
 {
 name = value;
 NotifyPropertyChange("Name");
 }
 }

 public int age;

 public int Age
 {
 get
 {
 return age;
 }
 set
 {
 age = value;
 NotifyPropertyChange("Age");
 }
 }

 public event PropertyChangedEventHandler PropertyChanged;

 private void NotifyPropertyChange(string propertyName)
 {
 if (PropertyChanged != null)
 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
 }
 }
}
<Window x:Class="ListViewDemo.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Title="MainWindow" Height="350" Width="525">
 <Grid>
 <ListView x:Name="listview1">
 <ListView.View>
 <GridView>
 <GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Path=Name}"/>
 <GridViewColumn Header="年龄" DisplayMemberBinding="{Binding Path=Age}"/>
 </GridView>
 </ListView.View>
 </ListView>
 <Button Content="更改名字" Click="Button_Click" Margin="315,174,35,103" />
 <TextBox Height="23" HorizontalAlignment="Left" Margin="162,180,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
 </Grid>
</Window>


我们只要输入名字,然后点击”button按钮”,最后ListView同步更新了,是不是很神奇的说。

五:依赖属性

依赖属性是wpf中独有的一种属性,前面文章中或许我们发现WPF的类定义中满是这些玩意,比如我们看一个TextBlock。


这些Property为后缀的都是叫做依赖属性,不过依赖属性这些东西深究起来内容还是比较多的,不过我还是讲究应用方面,有时候我们

可能有这样的需求,就是希望能在TextBlock上显示当前时间,这时我们就可以扩展TextBlock,在其中增加一个TimeProperty的依赖

属性来显示当前时间。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication12
{
 /// <summary>
 /// MainWindow.xaml 的交互逻辑
 /// </summary>
 public partial class MainWindow : Window
 {
 public MainWindow()
 {
 InitializeComponent();
 }
 }

 public class CustomTextBlock : TextBlock
 {
 //自定义一个依赖项属性
 public static DependencyProperty TimeProperty = DependencyProperty.Register("Timer", typeof(DateTime),
 typeof(CustomTextBlock),
 new PropertyMetadata(DateTime.Now, OnTimerPropertyChanged),
 ValidateTimeValue);
 /// <summary>
 /// 对依赖属性进行设置值
 /// </summary>
 public DateTime Time
 {
 get
 {
 //获取当前属性值
 return (DateTime)GetValue(TimeProperty);
 }
 set
 {
 //给当前的属性赋值
 SetValue(TimeProperty, value);
 }
 }

 static void OnTimerPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
 {

 }

 static bool ValidateTimeValue(object obj)
 {
 DateTime dt = (DateTime)obj;

 if (dt.Year > 1990 && dt.Year < 2200)
 return true;
 return false;
 }

 }
}
<Window x:Class="WpfApplication12.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:WpfApplication12"
 Title="MainWindow" Height="350" Width="525">
 <Grid>
 <local:CustomTextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=Timer}"/>
 </Grid>
</Window>


最后感谢一直关注此系列的朋友,希望你们有一丝收获。

时间: 2024-09-27 18:27:16

8天入门wpf—— 第八天 最后的补充的相关文章

8天入门wpf—— 第六天 细说控件

            这篇我们来大概的看一下WPF的各种神马控件,首先我们要知道所有的wpf控件都是继承自Control,从用途上可以分为四种          1:内容控件(Content Controls)          2:条目控件(Items Controls)          3:文本控件(Text Controls)          4:范围控件(Range Controls)   一:内容控件     内容控件的最大的特征就是有一个Content属性,从前面的文章中,我们

8天入门wpf—— 第七天 画刷

               这一篇我们聊聊wpf中的画刷,在wpf中如果想玩各种花哨,那么如何使用画刷则是我们的基本功,首先看一下类图 从图中可以看出,wpf有5种画刷和1种自定义画刷,都是继承自基类Brush,我们看看基类中有哪些好玩的东西. 这里有3个比较感兴趣的属性,分别属于"透明度"和"图像转换",好,下面我们一一解说.   一:SolidColorBrush(实心画刷)     实心画刷是我们用的最多的,也是最简单的一个,其实也就是填充色的意思,一个很简

8天入门wpf—— 第五天 数据绑定

             在webform中,如果提到"绑定"二字,相信大家都不会陌生,绑定,让我们的代码更加的简洁优美,在wpf中也存在各种神马的绑定, 当然使用上都是行隔理不隔.       一: 控件到控件的绑定      既然是绑定,那么肯定就有"源对象"和"目标对象"两种状态实体,从图的角度上来说存在三种状态: 确实在wpf中存在这三种模式的对应方式, 1:OneWay     正如图A所说,Source影响着Target,但是Targ

8天入门wpf—— 第二天 xaml详解

            首先我们还是新建一个空项目,看一下VS给我们默认生成的xaml结构. <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title=&qu

8天入门wpf—— 第一天 基础概念介绍

这些天从项目上接触到了wpf,感觉有必要做一个笔记,首篇还是聊聊基本的概念,要学习wpf,我们需要采用webform的思维来考虑问题. 一:App环境承载 我们都知道,console和winform程序的入口函数都是main,wpf同样也不例外,好了,我们新建一个wpf的程序,vs自动给我们生成了一个 MainWindow.xaml和App.xaml文件. 微软官方说wpf程序是从Application开始的,既然是开始总有个入口点吧,奇怪的是我们并没有发现Main函数,程序又是如何Run起来的

8天入门wpf—— 第三天 样式

说起样式,大家第一反应肯定是css,好的,先上一段代码. html{border:0;} ul,form{margin:0; padding:0} body,div,th,td,li,dd,span,p,a{font-size:12px; font-family:Verdana,Arial,"宋体";color:#575757;} h3,input{font-size:12px; font-family:Verdana,Arial,"宋体";color:#4465a

8天入门wpf—— 第四天 模板

今天说下wpf中的模板,前面一篇中我们讲到了style,但是style所能做的仅仅是在现有控件的基础上进行修修补补,但是如果我们想 彻底颠覆控件样式,那么我们就必须使用这一篇所说的模板. 老外写书都喜欢在篇头搞一个类图,方便我们宏观认识,这里我也上一个. 一:控件模板 1:ControlTemplate 我们知道wpf的控件都是继承自Control,在Control类中有一个Template属性,类型就是ControlTemplate. 那么利用这个ControlTemplate就可以彻底的颠覆

新手用WPF山寨QQ管家7.6(一)

原文 http://www.cnblogs.com/channingzhao/archive/2013/04/10/3012587.html     刚刚入门WPF,界面方面参考<基于Expression Blend 4中文版WPF和Silverlight项目设计基础> 一书学了一些,由于本人不是搞前台设计的,可是WPF做前台确实蛮好,加上公司要求做一个比较炫的界面,所以最后决定参考QQ管家的界面来做,接下来就是分享一下我这个新手边学边做的过程,因为都是笨办法来画,所以代码难免存在冗余....

求助代码问题wpf

问题描述 <StyleTargetType="s:SurfaceButton"x:Key="btn_product"><SetterProperty="Template"><Setter.Value><ControlTemplateTargetType="s:SurfaceButton"><BorderWidth="90"Height="70&