2012-03-24 85 views
0

WPF/MVVM的新手。我有一個類型爲「MyData」的數據對象。它的一個屬性是「MySubsetData」類型。如何將數據導入UserControl的ViewModel?

我在DataGrid中顯示「MyData」對象的集合。

<DataGrid ItemsSource="{Binding Path=MyDataCollection}"> 
    <!-- Each row of the datagrid contains an item of type "MyData" --> 
    <DataGrid.Columns .../> 
    <DataGrid.RowDetailsTemplate> 
     <DataTemplate> 
      <local:MySubsetDataUserControl/> 
     </DataTemplate> 
    </DataGrid.RowDetailsTemplate> 
</DataGrid> 

該行的詳細信息應顯示「MySubsetData」的內容。行細節的視圖位於一個單獨的用戶控件中(在這裏:「MySubsetDataUserControl」)。

此刻,我沒有爲「MySubsetDataUserControl」設置視圖模型,因此它從父級的datagrid行繼承數據上下文。

<UserControl> 
    <!-- Namespace stuff not shown for simplicity --> 
    <Grid DataContext="{Binding Path=MySubsetData}"> 
     <!-- Show the MySubsetData properties here --> 
     <!-- e.g. a textbox --> 
      <TextBox Text="{Binding Path=TextData, UpdateSourceTrigger=PropertyChanged}"/> 
    </Grid> 
</UserControl> 

Altough這工作我面對的幾個問題這種方法:

  1. 所有的業務邏輯將在用戶控件父母的視圖模型,它根本就不屬於。使視圖模型比它需要的更加混亂。更不用說用戶控件xaml中的命令綁定也非常難看。它只是感覺不對。

  2. 由於可以同時看到更多的行細節,因此我無法將「MySubsetData」的屬性綁定到視圖模型中的observable屬性。即如果我在代碼中更改屬性(例如TextData),則更改不會反映在視圖中。我的解決方法是不改變屬性「TextData」。相反,我更改了文本框Text屬性的內容,該屬性又將更新「TextData」屬性。那感覺非常錯誤!

所以我想用另一種觀點型號爲我的用戶控制,但我不知道如何訪問我的數據即可。

<UserControl.DataContext> 
    <local:UserControlViewModel/> 
</UserControl.DataContext> 

現在如何訪問「MySubsetData」?

回答

0

讓假設你有一個這樣的視圖模型:

public class ViewModel 
{ 
    public IEnumerable<MyData> MyDataCollection{get; private set;} 
} 

public class MyData 
{ 
    public MySubsetData MySubsetData { get; } 
} 

包含在DataGrid你的看法是

<UserControl.DataContext> 
    <local:ViewModel> 
</UserControl.DataContext> 

<DataGrid ItemsSource="{Binding Path=MyDataCollection}"> 
    <DataGrid.Columns .../> 
    <DataGrid.RowDetailsTemplate> 
     <DataTemplate> 
      <!-- each row of the items control has an implicit DataContext of MyData --> 
      <!-- so bind the DataContext of the subset control to MySubsetData --> 
      <local:MySubsetDataUserControl DataContext={Binding MySubsetData}/> 
     </DataTemplate> 
    </DataGrid.RowDetailsTemplate> 
</DataGrid> 

現在你的子控件可以像

<UserControl> 
    <Grid> 
     <TextBox Text="{Binding Path=TextData, UpdateSourceTrigger=PropertyChanged}"/> 
    </Grid> 
</UserControl> 

在重新閱讀這個問題時,也許我所做的只是以稍微不同的方式從問題中重複Xaml。

然而,各種類應該實現INotifyPropertyChanged,例如,

public class MySubsetData : INotifyPropertyChanged 
{ 
    public string TextData 
    { 
     get{...} 
     set{...; OnPropertyChanged("TextData"); } 
    } 
} 

然後綁定到TextData屬性的TextBox將反映在代碼中所做的更改。

+0

您的回答正確描述了我的設置。這就是我目前所做的。您只需在調用中設置用戶控件上下文,而我正在用戶控件網格中進行。所以你的更優雅,但不回答我的問題。 – UdoG 2012-03-26 08:37:09

+0

你說'如果我在代碼中更改屬性(例如TextData),更改將不會反映在視圖中'。如果視圖模型實現INotifyPropertyChanged並且TextData屬性引發OnPropertyChanged(「TextData」),它將會反映出來。 – Phil 2012-03-26 08:46:23

+0

這就是要點。假設我有兩行可見的細節。一行顯示「MyData1.MySubsetData.TextData」。另一個顯示「MyData2.MySubsetData.TextData」。所以數據網格視圖模型不能有一個可觀察的TextData屬性。或者我的錯誤在哪裏? – UdoG 2012-03-26 08:57:17