zoukankan      html  css  js  c++  java
  • WPF系列五

    先来了解一下什么是依赖属性,先来看看这段代码,大家很熟悉,但是为什么我要让大家看呢.

    <Window x:Class="WPF依赖属性.Window1"

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

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

    Title="Window1" Height="332" Width="501" Background="Tomato">

    //这是一个静态资源,大家很熟悉

        <Window.Resources>

            <SolidColorBrush x:Key="MyBrush" Color="Gold"/>

        </Window.Resources>

        <Grid>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="72*" />

                <ColumnDefinition Width="206*" />

            </Grid.ColumnDefinitions>

    //这里使用了静态资源,为什么他能认识上面的值呢,就是因为wpf的依赖属性机制实现的.

            <Button Background= "{StaticResource  MyBrush}" Content="1 使用依赖属性从资源动态获取参数" Height="47" VerticalAlignment="Top" Margin="38,62,30,0" Grid.ColumnSpan="2" />

            <Button Margin="38,115,30,124" Name="button1" Click="button1_Click" Grid.ColumnSpan="2">2 Get 依赖属性</Button>

            <TextBox Margin="38,0,120,16" Name="textBox1" Height="23" VerticalAlignment="Bottom" Grid.ColumnSpan="2">你好</TextBox>

            <Button Margin="38,0,30,86" Name="button2" Click="button2_Click" Grid.ColumnSpan="2" Height="23" VerticalAlignment="Bottom">3 Set 依赖属性</Button>

            <Button Height="23" Margin="38,0,30,45" Name="button3" VerticalAlignment="Bottom" Click="button3_Click" Grid.ColumnSpan="2">4 使用属性封装依赖属性</Button>

            <Label Height="45" Margin="105,11,90,0" Name="label1" VerticalAlignment="Top" FontSize="24" Grid.ColumnSpan="2">依赖属性演示  </Label>

        </Grid>

    </Window>

    依赖属性的我们使用了很多次的资源字典的形式来写,今天我们换一种方法使用.这个是后台代码我们一点点看.

    namespace WPF依赖属性

    {

        /// <summary>

        /// Window1.xaml 的交互逻辑

        /// </summary>

        public partial class Window1 : Window

        {

            public Window1()

            {

                InitializeComponent();          

            }

    //依赖属性今天要说的就是这些东西. 这行代码表示向wpf属性系统注册依赖属性

    //前三个参数,很简单,然后就是注册的值,后面跟着一个值发生改变的回调.

            private static readonly DependencyProperty myNameProperty = DependencyProperty.Register(

              "myName",

              typeof(string),

              typeof(Window1),

              new FrameworkPropertyMetadata(".NET Hello",

              FrameworkPropertyMetadataOptions.AffectsRender,

              new PropertyChangedCallback(OnMyNamePropertyChanged)

      )

    );

    //封装了注册的实例,便于访问.

            public string MyNameProperty

            {

                get { return this.GetValue(Window1.myNameProperty).ToString(); }

                set { SetValue(Window1.myNameProperty, value); }

            }

    //这是一个回调,只要注册的值发生了改变,就会弹出这个对话框.

            public static void OnMyNamePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

            {

                global::System.Windows.MessageBox.Show("值发生改变了...");

            }

    //通过GetValue的方式拿到注册的依赖属性值

            private void button1_Click(object sender, RoutedEventArgs e)

            {

                global::System.Windows.MessageBox.Show(this.GetValue(Window1.myNameProperty).ToString());

            }

    //使用SetValue对注册的依赖属性进行更改,这时候上面那个回调就会起作用了

            private void button2_Click(object sender, RoutedEventArgs e)

            {

                this.SetValue(Window1.myNameProperty, this.textBox1.Text);

                          //this.MyNameProperty = this.textBox1.Text;  //get set的使用,不说了

            }

    //通过封装的属性,来访问注册的依赖属性

            private void button3_Click(object sender, RoutedEventArgs e)

            {

                global::System.Windows.MessageBox.Show(this.MyNameProperty);

            }

        }

    }

    下面继续了解路由事件.先看一下wpf的事件的几种工作方式.

    直接方式,只有元素自身调用的事件

    冒泡方式,从根元素向根节点依次响应事件

    隧道方式,从根节点向根元素依次响应事件

    先来看一段隧道方式的事件代码,在wpf里面所有PreviewMouseDown这种P开头的事件都是隧道事件.

    <Window x:Class="绑定依赖属性路由.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 PreviewMouseDown="Grid_PreviewMouseDown">

            <Button Content="Button1" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="button1" VerticalAlignment="Top" PreviewMouseDown="button1_PreviewMouseDown" Width="75" />

        </Grid>

    </Window>

     

    前台就一个button按钮,grid和button都在使用同一种事件,看谁先响应.

    private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)

            {

                MessageBox.Show("Grid1");

                //e.Handled = true; 这句话的意思是  截断事件,如果截断了事件,就不会响应button的事件了.

            }

            private void button1_PreviewMouseDown(object sender, MouseButtonEventArgs e)

            {

                MessageBox.Show("button1");

            }

    后台就两个事件代码.其他的工作方式都是和以前一样,大家试试就知道了,只有隧道模式比较特殊.

    Wpf里面还可以通过这样来添加事件.新的特性.

    这是一个button的点击事件,很正常.

    private void Button_Click3(object sender, RoutedEventArgs e) {

    我们可以通过找到这个元素的name来添加事件. Grid.MouseDownEvent 这样就是为这个元素添加一个MouseDown事件.

                grid3.AddHandler(Grid.MouseDownEvent, new RoutedEventHandler(Grid_MouseDownNext), true);

                       }

            private void Grid_MouseDownNext(object sender, RoutedEventArgs e) {

                MessageBox.Show("Grid被点击");

      }

    下面来了解一个比较麻烦的例子,依赖事件.

    前台代码比较简单就是一个button按钮

     <Window x:Class="WPF_依赖事件.Window1"

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

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

        Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">

      

     <Grid>

            <Label Height="47" Margin="12,12,-7,0" Name="label1" VerticalAlignment="Top" FontSize="24">依赖事件演示</Label>

            <Button Height="23" Margin="59,0,21,64" Name="button1" VerticalAlignment="Bottom" >Send</Button>

        </Grid>

    </Window>

    后台代码比较麻烦

    namespace WPF_依赖事件

    {

        /// <summary>

        /// Window1.xaml 的交互逻辑

        /// </summary>

        public partial class Window1 : Window

        {

            public Window1()

            {

                InitializeComponent();

    ..通过这种方式来添加一个路由

                this.button1.AddHandler(Button.ClickEvent, new RoutedEventHandler(C));

    当然,还可以这样写

                //this.button1.Click += new RoutedEventHandler(button1_Click); 直接+=

                //this.button1.Click += (senders, es) => { }; 通过lambda

                //this.button1.Click += delegate { }; 匿名方法

    //这个事件比较是 自定义的一个事件

                this.okRoutedEvent += new RoutedEventHandler(Window1_okRoutedEvent);

            }

     

            void Window1_okRoutedEvent(object sender, RoutedEventArgs e)

            {

                global::System.Windows.MessageBox.Show(DateTime.Now.ToString());

            }

    //一个静态的只读性的事件字段

            private static readonly RoutedEvent okEvent = EventManager.RegisterRoutedEvent("okEvent", RoutingStrategy.Direct, typeof(RoutedEvent), typeof(RoutedEventArgs));

    //我们通过一种事件属性的写法 来访问这个事件

            public event RoutedEventHandler okRoutedEvent

            {

                add

                {

                    AddHandler(okEvent, value);

                }

                remove

                {

    RemoveHandler(okEvent, value);

                }

            }

    //这个是button点击的事件

            public void C(object o, RoutedEventArgs e)

            {

    //通过button点击来发布这个事件.

                RoutedEventArgs args = new RoutedEventArgs(okEvent);

                this.RaiseEvent(args);        //引发特定的路由事件   

            }

            private void Window_Loaded(object sender, RoutedEventArgs e)

            {

     

            }

        }

    }

    //总结来说,就是用 定义了一个路由事件.通过事件属性来访问, 让当前窗体使用这个事件, 然后通过 button的点击来发布这个事件,达到触发窗体 自定义的事件,非常好理解的一个逻辑.

    下章全部讲解数据绑定.

  • 相关阅读:
    hdu
    HUNAN 11567 Escaping (最大流)
    poj -1185 炮兵阵地 (经典状压dp)
    poj
    POJ 2955 Brackets (区间dp)
    csu
    poj
    CSU 1116 Kingdoms
    SPOJ-SQRBR Square Brackets
    退役贴
  • 原文地址:https://www.cnblogs.com/chenmengmeng/p/2331705.html
Copyright © 2011-2022 走看看