• databinding ObservableCollection易错之一:重新New一个新地址,不会自动通知UI


        刚用Databinding的同学会经常有各种各样失败的原因。最近在对Databinding对Collection做绑定的时候,犯了一个错误,感觉挺常见的,分享记录下:很多初学者大概以为ObservableCollection<>  任何改变的消息都会发一个事件告诉UI,但实际上是对ObservableCollection<>重新new一个地址,它并不会把新New 的地址发消息告诉UI,UI记录的source target的地址依然是之前的,除非你自己发消息告诉UI。

         用一个简单的Databinding的例子说明,如下:

        在UI 的ListBox绑定显示一个ObservableCollection<>,当点击了testButton后,在后台修改数据并显示。

     

    点击testButton后

    具体代码:

    In XAML:

    <UserControl x:Class="DataBindingReference.MainPage"

    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"

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">

    <ListBox ItemsSource="{Binding Path=MClassBs}" DisplayMemberPath="MText"/>

    <Button x:Name="textButton" Content="testButton" VerticalAlignment="Top" HorizontalAlignment="Left" Height="20" Width="80"Click="textButton_Click" Margin="0,61,0,0" />

    </Grid>

    </UserControl>

    定义了一个ClassB

    public class ClassB : ViewModelBase

        {

            public ClassB()

            {

                MText = "";

            }

            public ClassB(String showText)

            {

                MText = showText;

            }

            private String _mText;

            public String MText

            {

                get

                {

                    return _mText;

                }

                set

                {

                    if (_mText != value)

                    {

                        _mText = value;

                        OnPropertyChanged("MText");

                    }

                }

            }

    }

    再定义一个ClassA

        public classClassA :ViewModelBase

        {

            public ClassA()

            {

                MClassBs = new ObservableCollection<ClassB>();

                MClassBs.Add(new ClassB("MyName"));

                MClassBs.Add(new ClassB("HisName"));

            }

            public ObservableCollection<ClassB> MClassBs{get;set;}

        }

     

        对ClassADataBinding,注意注释部分Binding是错误的。因为你new 一个observableCollection <>后,mClass.MClassBs得到了新的地址,但是UI 一直记录的是原来的地址。所以新的地址并没有和UI产生DataBinding。

     

        public partialclassMainPage :UserControl

        {

            ClassA mClass;

            public MainPage()

            {

                InitializeComponent();

                mClass=new ClassA();

                LayoutRoot.DataContext = mClass;

            }

            private void textButton_Click(object sender,RoutedEventArgs e)

            {

               

                //mClass.MClassBs = new ObservableCollection<ClassB>();

                //mClass.MClassBs.Add(new ClassB("Hello"));

     

                mClass.MClassBs.Clear();

                mClass.MClassBs.Add(new ClassB("Hello"));

            }

        }

        如果要想注释的代码能work,必须给MClassBs赋值的时候,要发消息给UI知道。既然ObserverableCollection不发,我们自己发。修改ClassA如下:

    namespace DataBindingReference
    {
        public class ClassA : ViewModelBase
        {
            public ClassA()
            {
                MClassBs = new ObservableCollection<ClassB>();
                MClassBs.Add(new ClassB("MyName"));
                MClassBs.Add(new ClassB("HisName"));
            }

            private ObservableCollection<ClassB> mClassBs;
            public ObservableCollection<ClassB> MClassBs
            {
                get
                {
                    return mClassBs;
                }
                set
                {
                    if (mClassBs != value)
                    {
                        mClassBs = value;
                        OnPropertyChanged("MClassBs");
                    }
                }
            }
        }
    }

     这样子再运行一次注释的代码就ok了。。

     

     

  • 相关阅读:
    Delphi 控件使用谷歌浏览器控件chromium 安装包是 dcef3-20140522 --碰到的问题
    salesforce零基础学习(九十九)Git 在salesforce项目中的应用(vs code篇)
    Salesforce LWC学习(二十) CLI篇:新版本不支持Audience解决方案
    Salesforce LWC学习(十九) 针对 lightning-input-field的label值重写
    apt安装后需要移除的问题
    mysql 触发器阻止不合理数据插入
    本机环境virtualbox出现问题重装
    php 版本升级后需要对代码进行兼容性检测
    k8s使用需认证的私服仓库
    无法启动electron,提示node_modules/electron/dist/chrome-sandbox is owned by root and has mode 4755.
  • 原文地址:https://www.cnblogs.com/bester/p/3255766.html
Copyright © 2020-2023  润新知