最近研究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