2012-07-03 24 views
1

我正在創建一個應用程序,它的作用類似於某些Microsoft應用程序的「嚮導」組件。爲了表示這一點,我有兩個的ViewModels:以編程方式綁定到不斷變化的ViewModel

class WizardVm { 
    public string Name { get; set; } 
    public ICommand QuitCommand { get { /* ommitted */ } } 
    public WizardStepVm CurrentStep { get; set; } 
} 

class WizardStepVm { 
    public string StepName { get; set; } 
    public string StepText {get; set; } 
} 

在視圖中,WizardVm結合到窗口,並且WizardStepVm結合到窗口內的內容面板。我編程創建內容控制,並將其添加到WizardView這樣的:

// in the "DataContextChanged" handler for the WizardView 
var bn = new Binding("CurrentStep"); 
bn.Mode = BindingMode.OneWay; 

var contentControl = new ContentControl(); 
contentControl.SetBinding(ContentControl.ContentProperty, bn); 
WizardViewStackPanel.Children.Add(contentControl); 

這個正確呈現最初創建時WizardView。但是,如果CurrentStep發生更改,則視圖不會更新以反映此情況。 CurrentStep更改,但ContentControl繼續顯示原始WizardStepVm。此外,舊的WizardStepVm在內存中仍然存在,並且其字符串屬性仍然可以更改(從視圖中)。

這是爲什麼?我必須做些什麼才能使內容控件更改以反映ViewModel中綁定的更改?

(這裏實際上是對編程這樣一個很好的理由。然而,XAML解決方案也很受青睞。)

+0

擺脫「//在」WizardView的「DataContextChanged」處理程序「。 MVVM – blindmeis

回答

2

你的類需要實現INotifyPropertyChanged接口每次通知UI的它的屬性變化 之一:

class WizardStepVm : INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 
    private string m_stepName; 
    public string StepName { 
     get { 
     return m_stepName; 
     } 
     set { 
     m_stepName = value; 
     NotifyPropertyChanged("StepName"); 
     } 
    } 
    /* etc... */ 
} 
+0

哎呀!我的班確實沒有這個意思,而且這個財產被設置爲通知它何時發生變化。但是,更改所選步驟的方法是訪問基礎變量而不是屬性。 – Oliver

2

首先您的視圖模型應該執行INotifyPropertyChanged或只使用一次性BindingMode(見this後)

不過你可以做你想做很容易與視圖模型第一種方法是什麼和的DataTemplates

public class WizardVm { 
    public string Name { get; set; } 
    public ICommand QuitCommand { get { /* ommitted */ } } 
    public object CurrentStep { get; set; }//raise OnPropertyChanged("CurrentStep"); in your setter!! 
} 

public class WizardStep1Vm { 
    public string StepName { get; set; } 
    public string StepText {get; set; } 
} 

public class WizardStep2Vm { 
    public string StepName { get; set; } 
    public string StepText {get; set; } 
} 

window.xaml

<Window> 
<Window.Resources> 
    <DataTemplate DataType="{x:Type local:WizardStep1Vm}"> 
     <!--your view for step1 goes here--> 
     <local:MyStep1View/> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type local:WizardStep2Vm}"> 
     <!--your view for step2 goes here--> 
     <local:MyStep2View/> 
    </DataTemplate> 
</Window.Resources> 
    <Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition /> 
     <RowDefinition /> 
    </Grid.RowDefinitions> 

    <TextBlock Grid.Row="0" Text="{Binding Name}" /> 

    <ContentPresenter Content="{Binding CurrentStep}"/> 

    </Grid> 
</Window> 

當過你設置你的視圖模型的CurrentStep財產。您將在內容控制中看到正確的視圖。如果沒有,DataTemplate丟失;)

相關問題