WPF的数据绑定——MVVM模式下控件与类成员及类对象成员双向绑定

最近研究WPF,遇到并解决了一些难题(至少是初学者的入门难题),包括:

1)控件如何绑定数据?

2)控件与数据如何双向绑定?

3)控件如何绑定类成员变量?

4)控件如何绑定类对象的成员变量?

5)每次加载页面时,都会重新初始化,如何保持数据不变?

理论上的知识,就不一一详解了。这里写个小程序,解决上述提到的问题。

在创建新项目后,添加一个类TestViewMode,作为ViewMode。此类再调用其他类TempClass。如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace TestBinding
{
    class TestViewMode : INotifyPropertyChanged
    {          
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        //建立静态对象,以便复用
        public static TestViewMode vm = null;
        private TestViewMode()
        {
            strTempText = "这是ViewMode的一个成员变量";
            tc = new TempClass();
            tc.strName = "来自其他类的成员变量";
        }
        /// <summary>
        /// 创建ViewModel实例,先判断一下是否已存在,如已存在,则使用之前实例对象
        /// </summary>
        /// <returns>返回实例对象</returns>
        public static TestViewMode CreateInstance()
        {
            if (vm == null)
            {
                vm = new TestViewMode();
            }
            return vm;
        }
        /// <summary>
        /// 类内成员
        /// </summary>
        private string _strTempText = "";
        public string strTempText
        {
            get { return _strTempText; }
            set
            {
                _strTempText = value;
                OnPropertyChanged("strTempText");
            }
        }
        /// <summary>
        /// 类对象
        /// </summary>
        private TempClass _tc = null;
        public TempClass tc
        {
            get
            {
                return _tc;
            }
            set
            {
                _tc = value;
                OnPropertyChanged("TempClass");
            }
        } 
    }
    public class TempClass
    {
        public string strName { get; set; }
    }
}
在XAML添加控件,并绑定数据,如下:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="150" />
            <RowDefinition Height="*" />           
        </Grid.RowDefinitions>
        <Canvas Grid.Row="0">
            <Label Canvas.Left="57" Canvas.Top="30" Width="282" Height="33" Content="{Binding Path=strTempText}"/>
            <Label Canvas.Left="57" Canvas.Top="70" Width="282" Height="33" Content="{Binding Path=tc.strName}"/>             
        </Canvas>
        <Grid Grid.Row="1">
            <Frame Source="Page1.xaml"></Frame>
        </Grid>
    </Grid>
由上可见,两个Label控件分别绑定了类成员和类对象成员,上述XAML为了说明MVVM的优点,还嵌入了一个页面Page1。Page1的XAML如下:

    <Grid>
        <Canvas>
            <Label Canvas.Left="57" Canvas.Top="30" Width="282" Height="33" Content="{Binding Path=strTempText}"/>
            <Label Canvas.Left="57" Canvas.Top="70" Width="282" Height="33" Content="{Binding Path=tc.strName}"/>
        </Canvas>
    </Grid>
由上可见,两个XAML绑定相同的内容。

最后,需要将数据与各个页面的DataContext绑定起来,就在初始化中添加,如下:

MainWindow的初始化:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            TestViewMode vm = TestViewMode.CreateInstance();
            this.DataContext = vm;
        }
    }

Page1的初始化:

    public partial class Page1 : Page
    {
        public Page1()
        {
            InitializeComponent();
            TestViewMode vm = TestViewMode.CreateInstance();
            this.DataContext = vm;
        }
    }
运行,结果如下:




经调试,发现一个bug,即改变类对象成员的值后无法更新控件的值,无法实现双向绑定。

已另写文章说明,地址:http://blog.csdn.net/mandylover/article/details/70049436

现已修正,更新后的代码:http://download.csdn.net/detail/mandylover/9810572

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值