2009-07-06 6 views
5

Я в процессе внедрения шаблона MVVC, и у меня возникли проблемы с привязкой свойства в viewmodel изнутри DataTemplate в datagrid. Если у меня есть текстовый блок вне DataTemplate в столбце, он отлично работает (поскольку я непосредственно ссылаюсь на datacontext UserConrol, то есть на виртуальную машину), однако изнутри DataTemplate он не вернет свойство простого текста. Однако он вернет свойство из итерированного элемента IEnumerable.Silverlight DataGrid.Celltemplate Binding to 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. (Заметьте, я знаю, что 1-й текстовый блок вне DG не нуждается в ElementName и т. Д., Но я только что сделал это, чтобы доказать себе, что его ссылка на правильную вещь)

ответ

2

Я не знаю, относится ли это к SL, но вы можете проверить это:

«Коллекция колонок - это просто свойство в 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. Однако обходной путь в сообщении Хайме не будет работать для привязки данных между элементами, поэтому он не решает эту проблему. –

1

Вы все еще можете связать данные статические ресурсы внутри вашего DataTemplates даже когда элемент к элементу привязки данных не работает. Один метод представления для ссылки на модель представления в шаблоне MVVM - это сохранение модели представления в статическом ресурсе, например ViewModelLocator, используемом MVVM Light Toolkit.

Предполагая, что ваша модель просмотра называется 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> 
Смежные вопросы