2009-07-06 84 views
5

我正在实现MVVC模式的实现,并且无法从DataGrid中的DataTemplate中的视图模型中绑定属性。如果我在列的DataTemplate外面有一个textblock,它可以正常工作(因为我直接引用UserConrol的datacontext,即VM),但是从DataTemplate中它不会返回纯文本属性。然而,它会从迭代的IEnumerable项返回一个属性。Silverlight的DataGrid.Celltemplate绑定到ViewModel

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
    x:Class="Timesheet.Silverlight.Modules.Views.HistoryView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:Commands="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ViewModels="clr-namespace:Timesheet.Silverlight.Modules.ViewModels" 
    x:Name="View"> 
    <StackPanel>    
    <TextBlock Text="{Binding Path=DataContext.testText, ElementName=View}" />  
      <data:DataGrid Height="280" Width="500" ItemsSource="{Binding TimeSlots}" AutoGenerateColumns="False" >       
      <data:DataGrid.Columns> 
       <data:DataGridTextColumn Header="Allocation Area" Binding="{Binding TimeAllocationArea.TimeAllocationName}" Width="200" /> 
       <data:DataGridTextColumn Header="Start" Binding="{Binding StartTime}" Width="80" /> 
       <data:DataGridTextColumn Header="End" Binding="{Binding Path=DataContext.testText, ElementName=View}" Width="80" /> 
       <data:DataGridTemplateColumn Header="Modify" Width="200" > 
        <data:DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <StackPanel Orientation="Horizontal"> 
           <TextBlock Text="{Binding Path=DataContext.testText, ElementName=View}" /> 
          </StackPanel> 
         </DataTemplate> 
        </data:DataGridTemplateColumn.CellTemplate> 
       </data:DataGridTemplateColumn> 
      </data:DataGrid.Columns> 
     </data:DataGrid>  
    </StackPanel> 
</UserControl> 

是否存在某种与我无视DataTemplate的问题?注意“{Binding Path = DataContext.testText,ElementName = View}”适用于除DataTemplate中的所有元素外的所有元素。 (注意,我知道DG之外的第一个Textblock不需要ElementName等,但我刚刚通过这种方式来证明自己的参考是正确的)

回答

2

我不知道这是否适用于SL,但您可以查看下列内容:

“Columns集合只是Datagrid中的一个属性;此集合不在逻辑(或可视化)树中,因此DataContext未被继承,导致没有任何内容绑定到“。

http://blogs.msdn.com/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

+1

Jaime的文章特定于WPF,但明确解释了为什么这不适用于WPF和Silverlight。但是,Jaime的帖子中的解决方法不适用于元素到元素的数据绑定,所以它不能解决这个问题。 – 2010-07-14 20:09:06

1

,您仍然可以将数据绑定到静态资源你的DataTemplates内,即使元素与元素数据绑定不起作用。视图在MVVM模式中引用视图模型的一种方法是将视图模型存储在静态资源中,例如由MVVM Light Toolkit使用的ViewModelLocator。

假设您的视图模型名为TestViewModel,我可以修改您的示例XAML以使用ViewModelLocator并以此结束。

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
    x:Class="Timesheet.Silverlight.Modules.Views.HistoryView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:Commands="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ViewModels="clr-namespace:Timesheet.Silverlight.Modules.ViewModels" 
    x:Name="View" 
    DataContext="{Binding TestViewModel, Source={StaticResource Locator}}" 
    > 
    <StackPanel>    
     <TextBlock Text="{Binding Path=DataContext.testText, ElementName=View}" />  
     <data:DataGrid Height="280" Width="500" ItemsSource="{Binding TimeSlots}" AutoGenerateColumns="False" >       
      <data:DataGrid.Columns> 
       <data:DataGridTextColumn Header="Allocation Area" Binding="{Binding TimeAllocationArea.TimeAllocationName}" Width="200" /> 
       <data:DataGridTextColumn Header="Start" Binding="{Binding StartTime}" Width="80" /> 
       <data:DataGridTextColumn Header="End" Binding="{Binding Path=DataContext.testText, ElementName=View}" Width="80" /> 
       <data:DataGridTemplateColumn Header="Modify" Width="200" > 
        <data:DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <StackPanel Orientation="Horizontal"> 
           <!--<TextBlock Text="{Binding Path=DataContext.testText, ElementName=View}" />--> 
           <TextBlock Text="{Binding Source={StaticResource Locator}, Path=TestViewModel.testText}" /> 
          </StackPanel> 
         </DataTemplate> 
        </data:DataGridTemplateColumn.CellTemplate> 
       </data:DataGridTemplateColumn> 
      </data:DataGrid.Columns> 
     </data:DataGrid>  
    </StackPanel> 
</UserControl>