加载中...

第八天 最后的补充


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

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

一:用户控件(UserControl)

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

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

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

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

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

二:资源文件

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

wpf中也主张这么做。

 

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

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

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

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

三:了解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));
        }
    }
}

 

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

五:依赖属性

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

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

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

属性来显示当前时间。


还没有评论.