标签:element context component only 返回 标准 iter exe 解决
属性的语法正确,则可以将其视为可绑定的,这些语法规则称为约定。
所有公共实现的虚拟属性都是可绑定的
public virtual string Test { get; set; }
也可以禁止
[Bindable(false)]
public virtual string Test { get; set; }
带有字段的属性默认不可进行数据绑定,可以使用BindableProperty属性显式标记此类属性,以仍然能够将其用于数据绑定。
using DevExpress.Mvvm.DataAnnotations;
//. . .
string test;
[BindableProperty]
public virtual string Test
{
get { return test; }
set { test = value; }
}
属性依赖项是一种方法,当其相关属性更改或将要更改时,该方法将自动执行。
public virtual string Test { get; set; }
protected void OnTestChanged() {
//do something
}
为了实现属性依赖,属性依赖的方法必须要命名为On
public virtual string Test { get; set; }
protected void OnTestChanged() {
//do something
}
On
public virtual string Test { get; set; }
protected void OnTestChanging(string newValue) {
//do something
}
protected void OnTestChanged(string oldValue) {
//do something
}
自定义调用方法
[BindableProperty(OnPropertyChangingMethodName = "BeforeChange", OnPropertyChangedMethodName = "AfterChange")]
public virtual string Test { get; set; }
protected void BeforeChange() {
//. . .
}
protected void AfterChange() {
//. . .
}
事件处理程序转移到命令-封装特定操作的对象
在POCO ViewModels中void methods带有0或1个参数的都被视为命令
public void DoSomething(object p) {
MessageBox.Show(string.Format("The parameter passed to command is {0}.", p));
}
以 ...Command命名的方法会引发异常,需要在上面添加特定的特性,并通过设定Name来命名
using DevExpress.Mvvm.DataAnnotations;
[Command(Name="DoSomething")]
public void DoSomethingCommand(object p) {
//do something
}
对于每一个命令方法,框架都会生成相应的备用属性,这个属性会被默认命名为方法名Command通过Command特性的name可以为这个备用属性重命名。
[Command(Name = "MyMvvmCommand")]
public void DoSomething(object p) {
//do something
}
命令可以带有一个CanExecute的返回bool方法,用来指示方法是否可以被执行,同时该方法必须命名为Can
//this command will be executed only if "p" equals 4
public void DoSomething(int p) {
MessageBox.Show(string.Format("The parameter passed to command is {0}.", p));
}
public bool CanDoSomething(int p) {
return (2 + 2) == p;
}
可以通过Command特性的CanExecuteMethodName参数修改可以执行方法的名字
[Command(CanExecuteMethodName = "DoSomethingCriteria")]
public void DoSomething(int p) {
MessageBox.Show(string.Format("The parameter passed to command is {0}.", p));
}
public bool DoSomethingCriteria(int p) {
return (2 + 2) == p;
}
当命令刚刚绑定到目标时,首先检查CanExecute子句(以获取目标的初始状态)。以后每次CanExecuteChanged事件通知命令目标有关命令状态更改时,都会重新计算此标准。在基础命令对象级别声明此事件。要从ViewModel级别发送此类通知,请按如下所示调用RaiseCanExecuteChanged扩展方法。
//a bindable property
public virtual bool IsModified { get; protected set; }
//a command
public void Save() {
//. . .
}
//a CanExecute condition
public bool CanSave() {
return IsModified;
}
//the OnChanged method calls the RaiseCanExecuteChanged method for the "Save" command
//this forces the command to update its CanExecute condition
public void OnIsModifiedChanged() {
this.RaiseCanExecuteChanged(x=>x.Save());
}
用于为MVVM应用程序中的视图提供特定的UI感知功能的界面
为了解析服务,框架需要重写接口类型的虚拟属性,而且这些属性的名字都必须以Service结尾。
public virtual IMyNotificationService MyService {
get { throw new NotImplementedException(); }
}
public virtual IMyNotificationService AnotherService {
get { throw new NotImplementedException(); }
}
可以使用ServiceProperty特性来显示标注其他服务属性
using DevExpress.Mvvm.DataAnnotations;
//. . .
[ServiceProperty]
public virtual IMyNotificationService MyProvider {
get { throw new NotImplementedException(); }
}
当框架覆盖服务属性时,它将生成相应的GetService <>扩展方法调用。该ServiceProperty特性可以为这个方法传递一个特殊的参数(例如,业务密钥)。
[ServiceProperty(Key="Service1")]
public virtual IMyNotificationService Service {
get { throw new NotImplementedException(); }
}
[ServiceProperty(Key = "Service2")]
public virtual IMyNotificationService AnotherService {
get { throw new NotImplementedException(); }
}
若要将控件绑定到所需的数据,需要将相关的绑定添加到Control.DataBindings集合。例如有一个编辑器(textbox,editor)和viewmodel中的title属性进行绑定
editor.DataBindings.Add("EditValue", viewModel, "Title", true, DataSourceUpdateMode.OnPropertyChanged)
在运行时,必须可以更新UI元素的属性值,所以Viewmodel必须实现INotifyPropertyChanged接口.
public class LoginViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
string userNameCore;
public string UserName {
get { return userNameCore; }
set {
if(userNameCore == value) return;
this.userNameCore = value;
PropertyChangedEventHandler handler = PropertyChanged;
if(handler != null)
handler(this, new PropertyChangedEventArgs("UserName"));
}
}
}
从DevExpress提供的BindableBase 和 ViewModelBase类中派生ViewModels,这两个类已经实现了INotifyPropertyChanged 接口。
public class SampleViewModel : BindableBase {
string titleValue;
public string Title {
get { return titleValue; }
set { SetProperty(ref titleValue, value, "Title");}
}
}
绑定属性是使用的字符串名字,这样会有一个问题就是如果重新命名了但是编译器不会报错,最好是使用POCO属性
DevExpress MVVM Framework可以将上述代码简化
public class SampleViewModel {
public virtual string Title { get; set; }
}
这个简化的属性称为POCO(Plain Old CLR Objects)属性,该类称为POCO类,DevExpress MVVM Framework可以识别此类自动将该属性扩展,在上面代码里,POCO类包含一个string Title可绑定属性属性。绑定:
mvvmContext.SetBinding(editor, e => e.EditValue, "Title");
使用Fluent API实现相同的功能
var fluentAPI = mvvmContext.OfType<ViewModel>();
fluentAPI.SetBinding(editor, e => e.EditValue, x => x.Title);
使用 POCO ViewModels时,不需要隐式创建实例,有两种方法,
//SampleViewModel.cs
public static SampleViewModel Create() {
return ViewModelSource.Create<SampleViewModel>();
}
//MainViewModel.cs
var sampleViewModel = SampleViewModel.Create();
mvvmContext.ViewModelType = typeof(WindowsFormsApplication1.ViewModels.SampleViewModel);
实例:实例化viewmodel,将两个文本编辑器绑定到Operand1和Operand2,并将一个结果label绑定到ResultText,并使其具有关联的On ... Changed方法。两个文本编辑器的MaskProperties.MaskType 属性必须设置成 MaskType.Numeric.
//View
mvvmContext.ViewModelType = typeof(MultViewModel);
mvvmContext.SetBinding(editor1, e => e.EditValue, "Operand1");
mvvmContext.SetBinding(editor2, e => e.EditValue, "Operand2");
mvvmContext.SetBinding(resultLabel, l => l.Text, "ResultText");
//ViewModel
public class MultViewModel {
public MultViewModel() {
UpdateResultText();
}
public virtual int Operand1 { get; set; }
public virtual int Operand2 { get; set; }
public virtual int Result { get; set; }
public virtual string ResultText { get; set; }
// OnChanged callback is created for the Operand1 property from this method.
protected void OnOperand1Changed() {
UpdateResult();
}
// OnChanged callback is created for the Operand2 property from this method.
protected void OnOperand2Changed() {
UpdateResult();
}
// OnChanged callback is created for the Result property from this method.
protected void OnResultChanged() {
UpdateResultText();
}
void UpdateResult() {
Result = Operand1 * Operand2;
}
void UpdateResultText() {
ResultText = string.Format("The result of operands multiplication is: {0:n0}", Result);
}
}
另一个相同实现使用BindableProperty特性来指向NotifyResultAndResultTextChanged方法
//View
mvvmContext.ViewModelType = typeof(SumViewModel);
mvvmContext.SetBinding(editor1, e => e.EditValue, "Operand1");
mvvmContext.SetBinding(editor2, e => e.EditValue, "Operand2");
mvvmContext.SetBinding(resultLabel, l => l.Text, "ResultText");
//ViewModel
public class SumViewModel {
[BindableProperty(OnPropertyChangedMethodName = "NotifyResultAndResultTextChanged")]
public virtual int Operand1 { get; set; }
[BindableProperty(OnPropertyChangedMethodName = "NotifyResultAndResultTextChanged")]
public virtual int Operand2 { get; set; }
// We raise change notifications for the Result and ResultText properties manually
public int Result {
get { return Operand1 + Operand2; }
}
public string ResultText {
get { return string.Format("The result of operands summarization is: {0:n0}", Result); }
}
protected void NotifyResultAndResultTextChanged() {
this.RaisePropertyChanged(x => x.Result); // change-notification for the Result
this.RaisePropertyChanged(x => x.ResultText); // change-notification for the ResultText
}
}
POCO减轻了很多代码量,但重命名后会导致相关绑定失败。
使用Meta-POCO可以解决这个问题,
public virtual int Result { get; set; }
public virtual int Operand1 { get; set; }
public virtual int Operand2 { get; set; }
public string ResultText {
get { return string.Format("The result of operands summarization is: {0:n0}", Result); }
}
Meta-POCO声明:创建一个包含元数据的嵌套类,该嵌套类明确指定将哪些方法用作属性OnPropertyChanged回调的表达式。元数据类还可以使特定的POCO属性不可绑定。该嵌套类必须实现IMetadataProvider接口。下面的代码说明了ViewModel及其元数据声明。
[System.ComponentModel.DataAnnotations.MetadataType(typeof(Metadata))]
//ViewModel
public class SumViewModel_MetaPOCO {
public SumViewModel_MetaPOCO() {
}
protected void NotifyResultAndResultTextChanged() {
Result = Operand1 + Operand2;
}
// Metadata class for the SumViewModel_MetaPOCO
public class Metadata : IMetadataProvider<SumViewModel_MetaPOCO> {
void IMetadataProvider<SumViewModel_MetaPOCO>.BuildMetadata(MetadataBuilder<SumViewModel_MetaPOCO> builder) {
//Metadata
}
}
}
使用BuildMetadata方法,您可以遍历所有ViewModel属性并提供每个属性的行为。例如,在下面的代码中,Operand1和Operand2属性被视为引发OnPropertyChanged回调的可绑定属性。
public class Metadata : IMetadataProvider<SumViewModel_MetaPOCO> {
void IMetadataProvider<SumViewModel_MetaPOCO>.BuildMetadata(MetadataBuilder<SumViewModel_MetaPOCO> builder) {
builder.Property(x => x.Result)
.DoNotMakeBindable();
builder.Property(x => x.Operand1).
OnPropertyChangedCall(x => x.NotifyResultAndResultTextChanged());
builder.Property(x => x.Operand2).
OnPropertyChangedCall(x => x.NotifyResultAndResultTextChanged());
}
}
可以手动引发更改通知
protected void NotifyResultAndResultTextChanged() {
Result = Operand1 + Operand2;
this.RaisePropertyChanged(x => x.Result); // change-notification for the Result
this.RaisePropertyChanged(x => x.ResultText); // change-notification for the ResultText
}
需多数据类型的绑定是集合,ObservableCollection集合对象存储Test实例。该例子公开两个属性ID和Text,添加记录和删除记录两个公共方法。
public class Test {
public int ID { get; set; }
public string Text { get; set; }
}
public class TestViewModel {
public TestViewModel() {
Entities = new ObservableCollection<Test>();
}
public virtual Test SelectedEntity { get; set; }
public virtual ObservableCollection<Test> Entities { get; set; }
public void Add() {
Entities.Add(new Test() { ID = Entities.Count, Text = string.Format("Test {0}", Entities.Count) });
}
public void Remove(string title) {
Test element = Entities.Single<Test>(x => x.Text == title);
if (element != null) Entities.Remove(element);
}
}
利用MvvmContext组件的API,SetItemsSourceBinding 方法 可以绑定集合的每一个实例,并用实例填充tileControl的每一小块
mvvmContext1.ViewModelType = typeof(TestViewModel);
var fluentApi = mvvmContext1.OfType<TestViewModel>();
TileGroup group = tileControl1.Groups[0];
fluentApi.SetItemsSourceBinding(
group, //Target
g => g.Items, //Items Selector
x => x.Entities, //Source Selector
(tile, entity) => object.Equals(tile.Tag, entity), //Match Expression
entity => new TileItem() { Tag = entity }, //Create Expression
null, //Dispose Expression
(tile, entity) => ((TileItem)tile).Text = entity.Text); //Change Expression
此方法的参数说明
对象添加某些功能,而无需从内部对其进行修改。
View和ViewModel相互通信的方法
MVVM框架需要知道它应显示的特定视图
标签:element context component only 返回 标准 iter exe 解决
原文地址:https://www.cnblogs.com/lovexinyi/p/11980398.html