首页 > 其他分享 >WPF 控件驱动控件 及 数据驱动控件(双向绑定)

WPF 控件驱动控件 及 数据驱动控件(双向绑定)

时间:2023-12-04 10:00:43浏览次数:40  
标签:控件 wendu void 绑定 System 驱动 using WPF public

wpf 双向绑定

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

最近在知乎,看了很多提问,涉及到就业,裁员,经济等,不看不知道,越看越头疼,知乎上很多人提问

毕业生就业如何难,2023年裁员如何严重,35岁的中年危机,程序员被裁员后找不到工作该,经济如何差等话题

哎,这让我这个35岁的老程序员感到莫大的压力,我时常想,如果我离开了现在的公司,我能找到工作吗?多久能找到工作?如果找不到工作,我能干什么?

35岁,本是经验技术相对比较成熟的阶段,更是上有老下有小的年龄段,也是花钱多的时候,如果在这个年龄段没了收入,该多么绝望......,但没办法,世界就是如此,它不会顾及你的感受,生存法则而已

言归正传,在开始正文之前,小伙伴们看下知乎上提的一个话题:35岁了,还有必要继续卷技术吗? 你们认为呢?

本来鄙人也不打算继续内卷了,但中年危机的压迫感,迫使我不得不拿起手中的枪,继续战斗!我本是做web开发的,但C#语言似乎CS开发岗位更多,而且似乎不受年龄限制,大不了40岁进厂做工控机开发呗,再说了,厂里妹子不是多么,挺好的

1、事件驱动模式

这种方式类似于winform,不推荐使用

新建如下页面

WPF 控件驱动控件 及 数据驱动控件(双向绑定)_xml

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
        xmlns:local="clr-namespace:WpfApp" 
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="1080">
    <Window.Resources>
        <Style TargetType="Button" x:Key="baseStl">
            <Setter Property="Width" Value="200"/>
            <Setter Property="Height" Value="80"/>
            <Setter Property="Background" Value="Yellow"/>
            <Setter Property="FontSize" Value="22"/>

        </Style>
        <Style TargetType="Button" x:Key="Butn" BasedOn="{StaticResource baseStl}">
            <Setter Property="Content" Value="Btu"/>

        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Slider x:Name="slider" Maximum="100" Minimum="0"  ValueChanged="Slider_ValueChanged" Margin="5" Foreground="red" ></Slider>
            <TextBox x:Name="textbox1" Margin="5" Height="30"  TextChanged="TextBox_TextChanged"/>
            <TextBox x:Name="textbox2"  Margin="5" Height="30" TextChanged="TextBox_TextChanged" />
            <Button x:Name="button" Style="{StaticResource Butn}"  Command="{Binding BtnCommand}" Width="100" Height="100" Content="点我" />
        </StackPanel>
    </Grid>
</Window>

View Code

注意:Slider_ValueChanged 事件 及 TextBox_TextChanged 事件

代码如下:

private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            textbox1.Text = slider.Value.ToString();
            textbox2.Text = slider.Value.ToString();
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (double.TryParse(textbox1.Text, out double result))
            {
                slider.Value = result;
            } 
        }

View Code

这种模式最大的缺点是前后端混合在一起,不方便维护。下面介绍第二种方式,控件驱动控件。

2、控件驱动控件

新建如下页面

WPF 控件驱动控件 及 数据驱动控件(双向绑定)_xml_02

此时后台事件代码去掉,前端驱动事件去掉,xaml如下:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
        xmlns:local="clr-namespace:WpfApp" 
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="1080">
    <Window.Resources>
        <Style TargetType="Button" x:Key="baseStl">
            <Setter Property="Width" Value="200"/>
            <Setter Property="Height" Value="80"/>
            <Setter Property="Background" Value="Yellow"/>
            <Setter Property="FontSize" Value="22"/>

        </Style>
        <Style TargetType="Button" x:Key="Butn" BasedOn="{StaticResource baseStl}">
            <Setter Property="Content" Value="Btu"/>

        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Slider x:Name="slider" Maximum="100" Minimum="0"  Margin="5" Value="{Binding ElementName=textbox1,Path=Text,Mode=TwoWay}"  ></Slider>
            <TextBox x:Name="textbox1" Margin="5" Height="30" Text="{Binding ElementName=slider,Path=Value,Mode=TwoWay}" />
            <Button x:Name="button" Style="{StaticResource Butn}"  Command="{Binding BtnCommand}" Width="100" Height="100" Content="点我" />
        </StackPanel>
    </Grid>
</Window>

View Code

重点解读

<Slider x:Name="slider" Maximum="100" Minimum="0"  Margin="5" Value="{Binding ElementName=textbox1,Path=Text,Mode=TwoWay}"  ></Slider>

<TextBox x:Name="textbox1" Margin="5" Height="30" Text="{Binding ElementName=slider,Path=Value,Mode=TwoWay}" />

Slider 的 value 的取值为绑定模式,绑定的是元素Element的Name为 textbox1,取的是textbox1的text值,Mode模式为双向绑定绑定,(WPF默认模式为单向绑定模式)

TextBox 的 Text 的取值为绑定模式,绑定的是元素Element的Name为 slider,取的是slider的value值,Mode模式为双向绑定绑定,(WPF默认模式为单向绑定模式)

3、数据驱动模式(数据上下文模式)

需求要求:进度条初始值为20,点击按钮后,进度条的值变为88,且弹框提示

3.1、按钮点击需要用到Wpf的Command命令

新建BaseCommand类,并实现接口 ICommand

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace WpfApp.Models
{
    public class BaseCommand : ICommand
    {
        public Action action;
        public BaseCommand(Action action)
        {
            this.action = action;

        }
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            action();
        }
    }
}

View Code

3.2、先建viewModel如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows.Input;
using System.Messaging;
using System.Windows;

namespace WpfApp.Models
{
    public class MainWindowModel : INotifyPropertyChanged
    { 
        public ICommand BtnCommand { get; set; }
        public MainWindowModel()
        {
            //进度条模式为20
            this.wendu = 20;
            BtnCommand = new BaseCommand(DoBtnCommand);
        }

        public void DoBtnCommand()
        {
            this.wendu = 88;
            MessageBox.Show("进度条的值修改为88,进度条向前欢动了。");
        }
        private ushort _wendu;
        public ushort wendu
        {
            get { return this._wendu; }
            set
            {
                this._wendu = value;
                this.OnPropertyChanged("wendu");
            }
        }
     
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this,  new PropertyChangedEventArgs(propertyName));
            }
        }


    }
}

View Code

3.3、修改xaml的数据上下文

public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowModel(); 
        }

3.4、xaml如下

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
        xmlns:local="clr-namespace:WpfApp" 
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="1080">
    <Window.Resources>
        <Style TargetType="Button" x:Key="baseStl">
            <Setter Property="Width" Value="200"/>
            <Setter Property="Height" Value="80"/>
            <Setter Property="Background" Value="Yellow"/>
            <Setter Property="FontSize" Value="22"/>

        </Style>
        <Style TargetType="Button" x:Key="Butn" BasedOn="{StaticResource baseStl}">
            <Setter Property="Content" Value="Btu"/>

        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Slider x:Name="slider" Maximum="100" Minimum="0"  Margin="5" Value="{Binding wendu}"  ></Slider>
            <TextBox x:Name="textbox1" Margin="5" Height="30" Text="{Binding wendu}" />
            <Button x:Name="button" Style="{StaticResource Butn}"  Command="{Binding BtnCommand}" Width="100" Height="100" Content="点我" />
        </StackPanel>
    </Grid>
</Window>

View Code

3.5、另一种实现模式(主要是Command实现类)

ICommand的实现类(通过属性赋值Action委托,上面方法是通过构造函数赋值Action委托)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace WpfApp.Models
{
    /// <summary>
    /// 属性赋值action模式
    /// </summary>
    public class CommandBase : ICommand
    {
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// 是否可执行
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            action.Invoke(parameter);
        }

        public Action<object> action { get; set; }
    }
}

View Code

viewModel如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace WpfApp.Models
{
    public class MainWindowMod : INotifyPropertyChanged
    {
        //新建按钮点击事件
        public ICommand BtnCommand { get; set; }

        public MainWindowMod()
        {
            this.wendu = 20; 
            //执行委托
            BtnCommand = new CommandBase() { action = new Action<object>(DoBtnCommand) };
        }

        public void DoBtnCommand(object obj)
        { 
            this.wendu = 88; 
            MessageBox.Show("进度条的值修改为88,进度条向前欢动了。");
        }
        private ushort _wendu;
        public ushort wendu
        {
            get { return this._wendu; }
            set
            {
                this._wendu = value;
                this.OnPropertyChanged("wendu");
            }
        }
     

        /// <summary>
        /// 用于双向绑定
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

View Code

优化如下:

如果每次都需要写  "wendu" ,有可能会写错

this.OnPropertyChanged("wendu");

优化代码如下

public class MainWindowMod : INotifyPropertyChanged
    {
        //新建按钮点击事件
        public ICommand BtnCommand { get; set; }

        public MainWindowMod()
        {
            this.wendu = 20; 
            //执行委托
            BtnCommand = new CommandBase() { action = new Action<object>(DoBtnCommand) };
        }

        public void DoBtnCommand(object obj)
        { 
            this.wendu = 88; 
            MessageBox.Show("进度条的值修改为88,进度条向前欢动了。");
        }
        private ushort _wendu;
        public ushort wendu
        {
            get { return this._wendu; }
            set
            {
                this._wendu = value;
                this.OnPropertyChanged();
            }
        }
     

        /// <summary>
        /// 用于双向绑定
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName="")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

View Code

WPF 控件驱动控件 及 数据驱动控件(双向绑定)_ide_03

 

@天才卧龙的波尔卡



标签:控件,wendu,void,绑定,System,驱动,using,WPF,public
From: https://blog.51cto.com/u_15316082/8673558

相关文章

  • Windows驱动中使用数字签名验证控制设备访问权限
    1.背景  在一般的驱动开发时,创建了符号链接后在应用层就可以访问打开我们的设备并进行通讯。  但我们有时候不希望非自己的进程访问我们的设备并进行交互,虽然可以使用IoCreateDeviceSecure来创建有安全描述符的设备,但大数的用户账户为了方便都是管理员,因此该方法不太完整......
  • 分享一个LCD驱动框架
    首先需要说明的是本篇文章不是关于如何点亮一块LCD屏的教程,而是介绍一个LCD开发框架,更准确的说是介绍一个LCD的中间件(Middlwware),用来连接UI和不同类型的LCD屏。笔者本人的工作内容中很重要的一部分就是在不同的LCD屏上做UI开发,所以对如何最大程度复用LCD代码以及解耦屏驱有着一定......
  • 极语言3-15 Win32编程常用函数-公用图形库,图面说明类、颜色控件类、伽玛渐变类——成
    Win32编程常用函数-公用图形库中文名称英文名称示例作用图驱创建DirectDrawCreate图驱创建(标识,@接口,0)创建DirectDraw对象的实例。标识用设备GUID为硬件加速,用0为仿真;1模拟硬件支持;2纯仿真无硬件;成功返回0;图驱个例DirectDrawCreateClipper图驱个例(0,@接口,0)创建不与Direc......
  • Windows驱动中数字签名认证(使用 ci.dll)
    1.背景  对于常规应用程序来说,在应用层可以使用WinVerifyTrust,在驱动层使用常规的API无法使用,自己分析数据又太麻烦。  但在内核中ci.dll包装了数据签名验证相关的功能,我们可以使用该dll来实现我们的数字签名验证。  详细的分析见《内核中的代码完整性:深入分析ci......
  • 搭建Wpf框架(18) ——DataGrid实现右冻结
    19.搭建Wpf框架(18)——DataGrid实现右冻结先上效果图: 其中,Field3和Field4为右冻结列。将一下大致思路,1.在DataGrid右边再放一个DataGrid,用来显示右冻结的列,把冻结的列从左边的DataGrid移除。2.然后左边的DataGrid右侧的滚动条隐藏,横向滚动条显示,右边的DataDataGrid右侧......
  • 如何将 sap.ui.Table 控件的背景设置成透明
    笔者曾经写过一篇文章,介绍了如何在SAPUI5应用里设置背景图片:下图1是背景图片,图2是把这个背景图片加到SAPUI5应用之后的效果。https://blog.csdn.net/i042416/article/details/134643986后来有朋友追问:如果我的SAPUI5应用里使用的表格控件,没有用响应式表格sap.m.Tab......
  • 微软Windows硬件最新驱动下载地址,无讨论,版本新,都是硬件厂家上传
    下面地址可以下载Windows硬件最新驱动,这里下载的地址是纯粹的驱动,没有其他累赘。这里的驱动是硬件厂家上传的驱动,我查找的是realtek8852AE的驱动,其他任何地方找到的驱动都没有这里的新。realtek8852AE这款螃蟹无线网卡,联想,红米等很多厂家的笔记本都在用,但器旧版驱动容易出......
  • 一种LED驱动专用控制电路方案
    一、基本的概述TM1651是一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路,内部集成有MCU数字接口、数据锁存器、LED高压驱动、键盘扫描等电路。本产品性能优良,质量可靠。采用SOP16/DIP16的封装形式。二、特性说明采用功率CMOS工艺显示模式(7字段×4位),支持共阳数码管......
  • 8.4 Windows驱动开发:文件微过滤驱动入门
    MiniFilter微过滤驱动是相对于SFilter传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数IRP操作都由过滤管理器(FilterManager或Fltmgr)所接管,因为有了兼容层,所以在......
  • 7.2 Windows驱动开发:内核注册并监控对象回调
    在笔者上一篇文章《内核枚举进程与线程ObCall回调》简单介绍了如何枚举系统中已经存在的进程与线程回调,本章LyShark将通过对象回调实现对进程线程的句柄监控,在内核中提供了ObRegisterCallbacks回调,使用这个内核回调函数,可注册一个对象回调,不过目前该函数只能监控进程与线程句柄操......