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

<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的点击来发布这个事件,达到触发窗体 自定义的事件,非常好理解的一个逻辑.

下章全部讲解数据绑定.

相关文章:

  • 2022-02-11
  • 2021-07-19
  • 2021-11-07
  • 2021-06-27
  • 2021-06-09
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-07-12
  • 2021-09-09
  • 2022-01-04
  • 2022-01-11
  • 2021-06-05
相关资源
相似解决方案