• <menu id="w2i4a"></menu>
  • logo DevExpress WinForm中文手冊(cè)

    視圖模型管理


    立即下載DevExpress WinForms

    本文描述了如何在運(yùn)行時(shí)檢索ViewModel實(shí)例,注意如果您在設(shè)計(jì)時(shí)使用MvvmContext組件來(lái)構(gòu)建 MVVM-applications,該組件將自動(dòng)管理ViewModels。

    如果ViewModel遵循POCO概念,MVVM框架將動(dòng)態(tài)地把該ViewModel轉(zhuǎn)換為包含必要基礎(chǔ)結(jié)構(gòu)(例如,支持簡(jiǎn)化的數(shù)據(jù)綁定)的新類??蚣芘c動(dòng)態(tài)創(chuàng)建的類實(shí)例一起工作,這意味著您無(wú)法在運(yùn)行時(shí)初始訪問(wèn)這些實(shí)例,因?yàn)樗鼈兊念愋蜕形创_定。

    使用以下選項(xiàng)來(lái)檢索工作的ViewMode:

    • The ViewModelSource.Create method

    在這種方法中,您首先創(chuàng)建一個(gè)ViewModel實(shí)例,然后調(diào)用SetViewModel方法將該實(shí)例與特定的ViewModel類型關(guān)聯(lián)起來(lái)。

    C#:

    var mainViewModel = ViewModelSource.Create<MainViewModel>();
    mvvmContext1.SetViewModel(typeof(MainViewModel), mainViewModel);

    VB.NET:

    Dim mainViewModel = ViewModelSource.Create(Of MainViewModel)()
    mvvmContext1.SetViewModel(GetType(MainViewModel), mainViewModel)
    • The ViewModelBase class

    您可以從實(shí)現(xiàn)MVVM框架特性的ViewModelBase類中繼承ViewModels,在這種情況下,是可以直接創(chuàng)建ViewModel實(shí)例。注意,此時(shí)還需調(diào)用SetViewModel方法來(lái)指定框架在需要ViewModel時(shí)應(yīng)該使用這個(gè)實(shí)例。

    C#:

    public class ViewModel : ViewModelBase {
    //. . .
    }
    var myViewModel = new ViewModel();
    mvvmContext1.SetViewModel(typeof(ViewModel), myViewModel);

    VB.NET:

    Public Class ViewModel
    Inherits ViewModelBase
    
    '. . .
    End Class
    Private myViewModel = New ViewModel()
    mvvmContext1.SetViewModel(GetType(ViewModel), myViewModel)

    我們不推薦這種方法,因?yàn)槟鷮⑹OCO模型提供的所有特性。

    • ViewModelCreate events

    這種方法被設(shè)計(jì)為與依賴注入框架(如Ninject)一起工作,下面的例子說(shuō)明了這種注入是如何與Ninject 框架一起工作的。

    C#:

    public class SamuraiViewModel {
    public IWeapon Weapon { get; private set; }
    public SamuraiViewModel(IWeapon weapon) {
    this.Weapon = weapon;
    }
    public void Attack() {
    Weapon.Hit();
    }
    }
    
    // Bind a dependency for IWeapon
    kernel.Bind<IWeapon>().To<Sword>();
    
    // Set up MVVMContext
    var fluent = mvvmContext1.OfType<SamuraiViewModel>();
    fluent.BindCommand(simpleButton1, x => x.Attack());

    VB.NET:

    Public Class SamuraiViewModel
    Private privateWeapon As IWeapon
    Public Property Weapon() As IWeapon
    Get
    Return privateWeapon
    End Get
    Private Set(ByVal value As IWeapon)
    privateWeapon = value
    End Set
    End Property
    Public Sub New(ByVal weapon As IWeapon)
    Me.Weapon = weapon
    End Sub
    Public Sub Attack()
    Weapon.Hit()
    End Sub
    End Class
    
    ' Bind a dependency for IWeapon
    kernel.Bind(Of IWeapon)().To(Of Sword)()
    
    ' Set up MVVMContext
    Dim fluent = mvvmContext1.OfType(Of SamuraiViewModel)()
    fluent.BindCommand(simpleButton1, Function(x) x.Attack())

    在這種情況下,您需要?jiǎng)討B(tài)生成Viewmodel并將它們綁定到接口(當(dāng)將接口直接綁定到POCO時(shí),MVVM框架特性將丟失)。要獲得所需的實(shí)例,處理常規(guī)(本地)或靜態(tài)(全局)ViewModelCreate事件如下:

    C#:

    // Retrieve the live POCO ViewModel instance with the Ninject kernel
    //regular event
    mvvmContext1.ViewModelCreate += MVVMContext_ViewModelCreate;
    void MVVMContext_ViewModelCreate(object sender, DevExpress.Utils.MVVM.ViewModelCreateEventArgs e) {
    // kernel.Bind<SamuraiViewModel>().To(e.RuntimeViewModelType);
    // e.ViewModel = kernel.Get<SamuraiViewModel>();
    e.ViewModel = kernel.Get(e.RuntimeViewModelType);
    }
    //static event
    MVVMContextCompositionRoot.ViewModelCreate += (s,e)=> {
    e.ViewModel = kernel.Get(e.RuntimeViewModelType);
    };

    VB.NET:

    ' Retrieve the live POCO ViewModel instance with the Ninject kernel
    'regular event
    AddHandler mvvmContext1.ViewModelCreate, AddressOf MVVMContext_ViewModelCreate
    void MVVMContext_ViewModelCreate(Object sender, DevExpress.Utils.MVVM.ViewModelCreateEventArgs e)
    ' kernel.Bind<SamuraiViewModel>().To(e.RuntimeViewModelType);
    ' e.ViewModel = kernel.Get<SamuraiViewModel>();
    e.ViewModel = kernel.Get(e.RuntimeViewModelType)
    'static event
    AddHandler MVVMContextCompositionRoot.ViewModelCreate, Sub(s,e) e.ViewModel = kernel.Get(e.RuntimeViewModelType)

    靜態(tài)ViewModelCreate事件是一個(gè)weak event,如果它包含一個(gè)變量的閉包(上面示例中的" kernel "或下面 Autofac示例中的" rootContainer "范圍),其生命周期短于父容器的生命周期,那么VS垃圾收集器可能會(huì)過(guò)早地收集該變量,并且事件處理程序可能永遠(yuǎn)不會(huì)被調(diào)用。

    C#:

    [STAThread]
    static void Main() {
    //rootContainer is declared at the Main method level
    IContainer rootContainer;
    var builder = new ContainerBuilder();
    builder.RegisterType<TestViewModel>();
    builder.RegisterType<MyClass>().As<IService>();
    rootContainer = builder.Build();
    MVVMContextCompositionRoot.ViewModelCreate += (s, e) => {
    using (var scope = rootContainer.BeginLifetimeScope(
    b => b.RegisterType(e.RuntimeViewModelType).As(e.ViewModelType))) {
    e.ViewModel = scope.Resolve(e.ViewModelType);
    }
    };
    }

    VB.NET:

    <STAThread>
    Shared Sub Main()
    'rootContainer is declared at the Main method level
    Dim rootContainer As IContainer
    Dim builder = New ContainerBuilder()
    builder.RegisterType(Of TestViewModel)()
    builder.RegisterType(Of [MyClass])().As(Of IService)()
    rootContainer = builder.Build()
    AddHandler MVVMContextCompositionRoot.ViewModelCreate, Sub(s, e)
    Using scope = rootContainer.BeginLifetimeScope(Function(b) b.RegisterType(e.RuntimeViewModelType).As(e.ViewModelType))
    e.ViewModel = scope.Resolve(e.ViewModelType)
    End Using
    End Sub
    End Sub

    要解決潛在的問(wèn)題,請(qǐng)?jiān)趫?zhí)行訂閱的對(duì)象級(jí)別將變量聲明為屬性/字段。

    C#:

    //rootContainer is declared at the root level
    private static IContainer rootContainer { get; set; }
    [STAThread]
    static void Main()
    {
    var builder = new ContainerBuilder();
    builder.RegisterType<TestViewModel>();
    builder.RegisterType<MyClass>().As<IService>();
    rootContainer = builder.Build();
    MVVMContextCompositionRoot.ViewModelCreate += (s, e) =>
    {
    using (var scope = rootContainer.BeginLifetimeScope(
    b => b.RegisterType(e.RuntimeViewModelType).As(e.ViewModelType))) {
    e.ViewModel = scope.Resolve(e.ViewModelType);
    }
    };
    }

    VB.NET:

    'rootContainer is declared at the root level
    Private Shared Property rootContainer() As IContainer
    <STAThread>
    Shared Sub Main()
    Dim builder = New ContainerBuilder()
    builder.RegisterType(Of TestViewModel)()
    builder.RegisterType(Of [MyClass])().As(Of IService)()
    rootContainer = builder.Build()
    AddHandler MVVMContextCompositionRoot.ViewModelCreate, Sub(s, e)
    Using scope = rootContainer.BeginLifetimeScope(Function(b) b.RegisterType(e.RuntimeViewModelType).As(e.ViewModelType))
    e.ViewModel = scope.Resolve(e.ViewModelType)
    End Using
    End Sub
    End Sub
    掃碼咨詢


    添加微信 立即咨詢

    電話咨詢

    客服熱線
    023-68661681

    TOP
    三级成人熟女影院,欧美午夜成人精品视频,亚洲国产成人乱色在线观看,色中色成人论坛 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();