2011-10-25 55 views
2

我有一個MVVM的小問題。讓我先畫一下我的問題。ViewModel在需要之前實例化

我有一個父視圖(DashboardConsultants)有一個數據網格。在DataGrid中的每個單元都有一個提示,像這樣實現的:

<UserControl.Resources> 
     <ResourceDictionary> 
      <DataTemplate DataType="{x:Type vm:UC1001_AgreementDetailsViewModel}"> 
       <v:UC1001_AgreementDetails_View /> 
      </DataTemplate>  
     </ResourceDictionary> 
</UserControl.Resources> 

<DataGridTextColumn.ElementStyle> 
     <Style TargetType="{x:Type TextBlock}"> 
     <Setter Property="DataGridCell.ToolTip"> 
       <Setter.Value> 
        <vm:UC1001_AgreementDetailsViewModel /> 
       </Setter.Value> 
     </Setter> 

工具提示我想起了我的ViewModel(AgreementDetailsViewModel),它具有以下代碼:

public UC1001_ActiveAgreementContract AgreementDetailsContract { get; set; } 

public int AgreementID { get; set; } 

public UC1001_AgreementDetailsViewModel() 
{ 
    AgreementDetailsContract = new UC1001_ActiveAgreementContract(); 
    this.Initialize(); 
} 

private void Initialize() 
{ 
    GetRefData(); 
    ShowAgreementDetailsView(); 
} 

private void GetRefData() 
{ 
    UC1001_ActiveAgreementArguments args = new UC1001_ActiveAgreementArguments(); 
    args.AgreementID = 3; 
    DefaultCacheProvider defaultCacheProvider = new DefaultCacheProvider(); 
    if (!defaultCacheProvider.IsSet("AgrDet:" + args.AgreementID)) 
    { 
     ConsultantServiceClient client = new ConsultantServiceClient(); 

     AgreementDetailsContract = client.GetAgreementDetailsByAgreementID(args); 
     defaultCacheProvider.Set("AgrDet:" + args.AgreementID, AgreementDetailsContract, 5); 
    } 
    else 
    { 
     AgreementDetailsContract = (UC1001_ActiveAgreementContract)defaultCacheProvider.Get("AgrDet:" + args.AgreementID); 
    } 
} 


private void ShowAgreementDetailsView() 
{ 
    // Initialize 
    var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>(); 

    // Show content 
    var agreementDetailsWorkspace = new Uri("UC1001_AgreementDetails_View", UriKind.Relative); 
    regionManager.RequestNavigate("ContentRegion", agreementDetailsWorkspace); 
} 

視圖模型的目標是從數據庫中獲得一個協議(目前是靜態的...),然後將它傳遞給子View(UC1001_AgreementDetails_View)以顯示爲工具提示。子視圖具有以下構造這樣的控件可以綁定到合同:

public UC1001_AgreementDetails_View(ViewModels.UC1001_AgreementDetailsViewModel UC1001_AgreementDetailsViewModel) 
    {    
     InitializeComponent(); 
     this.DataContext = UC1001_AgreementDetailsViewModel.AgreementDetailsContract; 
    } 

我把一個斷點視圖模型初始化,當我得到父視圖它觸發,但是當我得到它應該火在子視圖上(因此在數據網格中打開工具提示時)。有誰知道我該如何解決這個問題?

如果需要,可以提供更多信息/代碼。

編輯:

我嘗試了一些東西,我現在我有這樣的事情(我覺得是有點接近的解決方案)。

我改變了我提示以下(根據Rachels幫助):

<Setter Property="DataGridCell.ToolTip"> 
      <Setter.Value> 
       <v:UC1001_AgreementDetails_View DataContext="{Binding AgreementDetailsViewModel}" /> 
      </Setter.Value> 
</Setter> 

在我的孩子的看法,我把下面結合

<Label Content="{Binding AgreementDetailsContract.Header}" Height="50" HorizontalAlignment="Left" Margin="8,6,0,0" Name="_labelHoofding" VerticalAlignment="Top" FontSize="22" /> 

現在我AgreementDetailsViewModel,其中有一個屬性稱爲AgreementDetailsContract以及我想要顯示的所有信息,是我的子視圖的DataContext。但我的問題依然存在。 AgreementDetailsViewModels觸發打開ConsultantDashboard,當它顯示工具提示時它應該打開。是否有某種事件/命令可以放在提示視圖模型的工具提示上?另外,我認爲我的標籤綁定有些問題,因爲它沒有顯示信息(儘管這可能與ViewModel沒有傳遞正確信息的問題相同)。再次,如果它看起來有點複雜,我會很樂意進一步解釋它,或者如果詢問更多的代碼,我會很高興。

解決:

我得到了解決。我在ChildView的構造函數中指定綁定,而不是在其XAML或View視圖工具提示中。

public UC1001_AgreementDetails_View() 
    { 
     InitializeComponent(); 
     this.DataContext = new UC1001_AgreementDetailsViewModel(); 
    } 
+4

請投資一份框架設計指南。要麼自己閱讀,要麼打敗決定你的類型名稱形式的人。另外,更嚴重的一點是,您是否嘗試製作一個非常簡單的原型,其中的repro是您的問題?你似乎在做很多複雜的東西,可能會以幾種不同的方式破解...... – Will

+0

功能的一般概念並不那麼難。我只想顯示一個視圖作爲提供來自ViewModel的數據的工具提示。這是我第一次使用WPF和MVVM,所以我真的不知道如何自己解決這個問題:) –

+1

工具提示存在於邏輯樹之外,因此它們不像預期的那樣繼承DataContext。我無法花費足夠的時間來查看你的問題,以確定這是否是你的問題的根源。您可以在這裏搜索數據綁定工具提示並查找涉及這些問題的很多問題。我想我已經在這個主題上發佈了一些答案... – Will

回答

3

它看起來像你的觀點是直接引用視圖模型,這意味着當它啓動時

該代碼會造成你的視圖模型的副本

<Setter Property="DataGridCell.ToolTip"> 
    <Setter.Value> 
     <vm:UC1001_AgreementDetailsViewModel /> 
    </Setter.Value> 
</Setter> 

應該

<Setter Property="DataGridCell.ToolTip"> 
    <Setter.Value> 
     <!-- If you want to keep the DataTemplate, use a ContentControl --> 
     <v:UC1001_AgreementDetails_View DataContext="{Binding AgreementDetails}" /> 
    </Setter.Value> 
</Setter> 

您的數據結構應該如下所示:

class MainViewModel 
{ 
    ObservableCollection<AgreementViewModel> Agreements; 
} 

class AgreementViewModel 
{ 
    // Loaded only when getter is called 
    AgreementDetailViewModel AgreementDetails; 
} 
+0

+1這是顯而易見的答案! – Venemo

+0

我嘗試了一些東西,並更新了我的答案。 –

+0

我得到了解決方案,檢查我的問題。我把你的答案作爲接受,因爲答案幫助我一路走來。謝謝! –

相關問題