WPF 零基础入门笔记(3):数据绑定详解(更新中)

这篇具有很好参考价值的文章主要介绍了WPF 零基础入门笔记(3):数据绑定详解(更新中)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文章合集

WPF基础知识博客专栏
WPF微软文档
WPF控件文档

B站对应WPF数据绑定视频教程

数据绑定

我们在之前的文章中,详细解释了数据模版和控件模板。简单来说数据模板和控件模板就是为了解决代码重复的问题。我们可以回顾一下之前的所有内容。

  • 为了不写重复的样式,WPF提供了样式设置
  • 为了减少业务代码和界面之间的沟通,WPF将简单的交互逻辑设计到了触发器
  • 为了重复使用复杂控件,WPF开发了控件模板
    • 控件模板又分为
    • 多标签复合
    • 标签元素拆分
    • 标签子项重写

这个时候,为了数据的高效绑定,为了实现事件驱动到数据驱动的转变,我们要进行数据绑定。

数据绑定实战

WPF 零基础入门笔记(3):数据绑定详解(更新中)
基础样式

        <StackPanel>
            <Slider x:Name="sd" Width="200" />
            <TextBox x:Name="txt" HorizontalAlignment="Center"  Text="50"/>
        </StackPanel >

事件通知型

WPF 零基础入门笔记(3):数据绑定详解(更新中)

xml代码

        <StackPanel>
            <Slider x:Name="sd" Width="200" ValueChanged="sd_ValueChanged"/>
            <TextBox x:Name="txt" HorizontalAlignment="Center"  Text="50"/>
        </StackPanel >

cs代码

        private void sd_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txt.Text = e.NewValue.ToString();
        }

实现效果

WPF 零基础入门笔记(3):数据绑定详解(更新中)

数据驱动,双向绑定

我们这里还是事件驱动,就是一个滑块移动事件来设置属性。WPF为了将这种简单的交互脱离业务逻辑,我们可以直接页面元素之间进行数据绑定。

        <StackPanel>
            <Slider x:Name="sd" Width="200" />
            <TextBox x:Name="txt" HorizontalAlignment="Center"  Text="{Binding ElementName=sd, Path=Value}"/>
        </StackPanel >

这个代码实现了双向绑定,而且没有在CS代码中写逻辑。这个是纯数据驱动事件。让我们的业务代码专心于业务。

WPF 零基础入门笔记(3):数据绑定详解(更新中)
WPF 零基础入门笔记(3):数据绑定详解(更新中)

功能
Default 同TowWay。双向绑定
OneTime 只响应一次
OneWay 单向正绑定
OneWayToSource 单向负绑定
TwoWay 双向绑定

这里推荐大家用双向绑定,而且大部分业务也是双向绑定的业务。如果有特殊需求再更改。

资源绑定

我们还可以绑定静态资源

<Window.Resources>
        <TextBox x:Key="txt">Hello WPF!</TextBox>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <TextBox FontSize="50" Text="{Binding Source={StaticResource txt},Path=Text}"/>
        </StackPanel >
    </Grid>

WPF 零基础入门笔记(3):数据绑定详解(更新中)

数据源绑定

我们之前都是前端的数据交互,我们希望直接绑定后端数据。通过使用dataContext来实现

        <StackPanel>
            <TextBox x:Name="txt" FontSize="50" Text="{Binding Name}"/>
        </StackPanel >
 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ///获取前端名为txt的数据,传入数据源
            txt.DataContext = new Person()
            {
                Name = "Hello C#"
            };


        }

    }
     public class Person
    {
        public string Name { get; set; }
    }

WPF 零基础入门笔记(3):数据绑定详解(更新中)
注意,这里一定是传入一个类,这样才能绑定这个类的某个值。而且不能用已经存在的关键字命名。

全局数据源

我们一个一个绑定数据源太麻烦,所以我们可以设置全局数据源,把整个窗体的数据源都绑定上去。
新建一个MainViewModel类
WPF 零基础入门笔记(3):数据绑定详解(更新中)

    public class MainViewModel
    {
        public MainViewModel() {
            Name = "Hello WPF!";
        }
        public string Name { get; set; }
    }

在MainWindow.xmal.cs中引入MainViewModel


    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //给整个窗口设置数据源
            this.DataContext = new MainViewModel();
        }

    }

直接绑定

    <Grid>
        <StackPanel>
            <TextBox FontSize="50"
                     Text="{Binding Name}" />
            <TextBox FontSize="50"
                     Text="{Binding Name}" />
            <TextBox FontSize="50"
                     Text="{Binding Name}" />

            <TextBox FontSize="50"
                     Text="{Binding Name}" />

        </StackPanel >
    </Grid>

WPF 零基础入门笔记(3):数据绑定详解(更新中)

后端和前端绑定问题

这里是单向绑定,后端代码更新是不影响前端的,要主动渲染。前端代码更新影响后端。

前端不重新渲染示例代码

    <Grid>
        <StackPanel>
            <TextBox FontSize="50"
                     Text="{Binding Name}" />
            <TextBox FontSize="50"
                     Text="{Binding Name}" />
            <TextBox FontSize="50"
                     Text="{Binding Name}" />

            <TextBox FontSize="50"
                     Text="{Binding Name}" />
            <Button Click="Button_Click" Height="100" FontSize="50" Content="按钮"/>

        </StackPanel >
    </Grid>
    public partial class MainWindow : Window
    {
        MainViewModel data = new MainViewModel();

        public MainWindow()
        {
            InitializeComponent();
            //给整个窗口设置数据源
            this.DataContext = data;



        }
		//我们添加按钮事件同时打印值
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            data.Name = "data change!";
            MessageBox.Show(data.Name);
        }
    }

WPF 零基础入门笔记(3):数据绑定详解(更新中)

继承事件通知,刷新数据

在原来的基础上

    /// <summary>
    /// 继承INotifyPropertyChanged
    /// </summary>
    public class MainViewModel: INotifyPropertyChanged
    {
        public MainViewModel() {
            Name = "Hello WPF!";
        }


        /// <summary>
        /// 使用public类,不然无法双向绑定
        /// </summary>
        public string Name { get;set; }

        /// <summary>
        /// 重载事件类,不然会报错
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;


    }

成功改变

WPF 零基础入门笔记(3):数据绑定详解(更新中)

我们将MainWindow.xmal.cs的点击按钮改造一下,看看多次点击会不会改变


   public partial class MainWindow : Window
    {
        MainViewModel data = new MainViewModel();

        public MainWindow()
        {
            InitializeComponent();
            //给整个窗口设置数据源
            this.DataContext = data;



        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            data.Name += "!";
            MessageBox.Show(data.Name);
        }
    }
事件通知强制刷新(无效)

我把代码修改了一下,发现并不是强制通知,而是触发了事件,或者有点点击事件之后才会触发通知

MainViewModel代码

        public MainViewModel() {
            Name = "Hello WPF!";
            Task.Run(async () =>
            {
                await Task.Delay(3000);
                Name = "I have been changed!";

                MessageBox.Show(Name);

            });
        }


        /// <summary>
        /// 使用public类,不然无法双向绑定
        /// </summary>
        public string Name { get;set; }

        /// <summary>
        /// 重载事件类,不然会报错
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

WPF 零基础入门笔记(3):数据绑定详解(更新中)
如果你鼠标不动,则最多停留10s钟才会刷新,如果鼠标动一动就立刻刷新

 public class MainViewModel: INotifyPropertyChanged
    {
        public MainViewModel() {
            Name = "Hello WPF!";
            //Name = "I have been changed!";

            Task.Run(async () =>
            {
                await Task.Delay(3000);
                Name = "I have been changed!";

                //MessageBox.Show(Name);

            });
        }


        /// <summary>
        /// 使用public类,不然无法双向绑定
        /// </summary>
        private string _name;

        /// <summary>
        /// 当修改时触发
        /// </summary>
        public string Name
        {
            get { return _name; }
            set { _name = value; OnPropertyChanged("Name"); }
        }


        /// <summary>
        /// 重载事件类,不然会报错
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 强制事件通知
        /// </summary>
        /// <param name="propertyName"></param>

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }


    }

结果还是一样。我估计是懒重载吧,就是WPF认为这个不是活动窗口,所以刷新频率低一点,这个其实是个优化吧,多窗口默认优化。

补充说明:2023年7月15日

根据我的测试。如果想要实先列表的数据绑定,比如我传入一个List<Student>类,Student有Name,Age参数。需要注意一下几点。

使用ObservableCollection

ObservableCollection是集成了INotifyPropertyChanged的集合,会在Count即个数出现变化的时候进行通知

在Student里面设置通知

进入如下参数设置

 public class MyListBoxItem : INotifyPropertyChanged
    {
        public string Text
        {
            get { return text; }
            set
            {
                text = value;
                OnPropertyChanged("Text");
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;
		
		//通知函数
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

安装prism框架,使用封装好的更新

Nuget安装

WPF 零基础入门笔记(3):数据绑定详解(更新中)

    public class MyListBoxItem : BindableBase
    {
        private string text;
        public string Text
        {
            get { return text; }
            set {  SetProperty(ref text, value);}//此方法为Prism提供
        }
    }

可以输入propp加tab键,模板输入,提交写代码效率

WPF 零基础入门笔记(3):数据绑定详解(更新中)

我还是没有找到最优雅的解决方案,理论上最优解为:

  • 继承一个接口,所有的公共变量自动通知
  • 使用一个注解,被注解的参数自动赋值
  • 不需要定义私有类。

我只能猜测可能所有公共变量自动通知太过于危险了,需要我们手动输入。因为有模板输入,写代码也不是特别麻烦。

结论:

继承INotifyPropertyChanged,扩不扩展public属性,感觉效果差不多。出于简洁的目的,我们在WPF项目中就不用扩展了。文章来源地址https://www.toymoban.com/news/detail-502919.html

到了这里,关于WPF 零基础入门笔记(3):数据绑定详解(更新中)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WPF基础入门-Class4-WPF绑定

    Class4:WPF绑定 一、简单绑定数据 1、cs文件中设置需要绑定的数据: 2、编写xaml绑定 3、效果显示: 二、控件绑定 1、 Binding ElementName :绑定的元素 2、 Path=绑定的属性 3、 Mode :绑定的模式,default双向榜单TwoWay Mode绑定模式,onetime只改变一次 default默认双向 OneWay只能受到影响

    2024年02月11日
    浏览(37)
  • WPF绑定单变量Binding和绑定多变量MultiBinding 字符串格式化 UI绑定数据,数据变化自动更新UI,UI变化自动更新数据

    UI绑定数据,数据变化自动更新UI,UI变化自动更新数据。 支持多设备,同时下载。 在WPF (Windows Presentation Foundation) 中,您可以使用数据绑定来将变量绑定到界面元素。这允许您在界面上显示变量的值,并使这些值能够自动更新,而不需要手动更新界面。以下是如何绑定变量到

    2024年02月07日
    浏览(42)
  • WPF绑定数据,增删改后实时更新TreeView/ListView

    WPF的界面的确好看,也引入了很多新功能,和winform相比更先进更强大......那么狗儿蛋,代价是什么? 代价就是WPF学起来比较费力。 数据绑定是WPF的特色之一,可以省去写代码更新UI界面的工作。这次打算做一个管理数据的小软件,自然的我也打算在界面上弄个TreeView,然后把

    2024年02月09日
    浏览(55)
  • WPF实战学习笔记29-登录数据绑定,编写登录服务

    添加登录绑定字段、命令、方法 修改对象:Mytodo.ViewModels.ViewModels 添加密码依赖对象行为 添加文件:Mytodo.Extensions.PassWordExtensions ### 登录UI添加密码行为 修改文件:Mytodo.Views.LoginView.xmal 添加命名空间,略 修改passbox。 添加加密方法,并使用 添加文件:MyToDo.Share.StringE

    2024年02月15日
    浏览(37)
  • 【WPF】异步任务更新UI、绑定命令、绑定字符串属性

    WPF异步任务 主界面 在视图模型中定义命令: 在主界面xaml中绑定命令:  创建命令实例:

    2024年02月09日
    浏览(62)
  • WPF 入门笔记 - 03 - 样式基础

    ? 程序的本质 - 数据结构 + 算法 ? ?本篇为学习李应保老师所著的《WPF专业编程指南》并搭配 WPF 开发圣经《WPF编程宝典第4版》以及痕迹大佬《WPF入门基础教程系列》文章所作笔记,对应《WPF专业编程指南》第 9 章之间内容,主要概述 WPF 中关于样式的相关内容,希望可以帮到

    2024年02月08日
    浏览(45)
  • WPF 入门笔记 - 01 - 入门基础以及常用布局

    🥑本篇为学习博客园大佬圣殿骑士的《WPF基础到企业应用系列》以及部分DotNet菜园的《WPF入门教程系列》所作笔记,对应圣殿骑士《WPF基础到企业应用系列》第 1 - 6 章之间内容,包括 WPF 项目结构、程序的启动和关闭、程序的生命周期、继承关系以及常见的布局控件及其应用

    2024年02月05日
    浏览(42)
  • WPF 入门笔记 - 03 - 样式基础及模板

    🍟 程序的本质 - 数据结构 + 算法 🍟 本篇为学习李应保老师所著的《WPF专业编程指南》并搭配 WPF 开发圣经《WPF编程宝典第4版》以及痕迹大佬《WPF入门基础教程系列》文章所作笔记,对应《WPF专业编程指南》第 9-10 章之间内容,主要概述 WPF 中关于样式及模板部分的梳理及应

    2024年02月08日
    浏览(42)
  • WPF 零基础入门笔记(1):WPF静态页面,布局+样式+触发器

    WPF 零基础入门笔记(0):WPF简介 WPF MaterialDesign 初学项目实战(0):github 项目Demo运行 WPF MaterialDesign 初学项目实战(1)首页搭建 WPF MaterialDesign 初学项目实战(2)首页导航栏样式 WPF MaterialDesign 初学项目实战(3)动态侧边栏 WPF MaterialDesign 初学项目实战(4)侧边栏路由管理

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包