2010-07-07 85 views
0

我想要使用ViewModel声明式绑定DataGrid CellEditingTemplate中的ComboBox。 ComboBox没有被绑定。我究竟做错了什么?Silverlight MVVM - 如何使用ViewModel声明式绑定DataGrid CellEditingTemplate中的组合框?

XAML:

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" 
    xmlns:data="clr-namespace:SilverlightApplication1" 
    mc:Ignorable="d" 
    x:Class="SilverlightApplication1.EmployeeDetail" 
    Width="640" Height="480"> 

    <UserControl.Resources> 
     <data:EmployeeDetailsViewModel 
      x:Key="ViewModel" 
      d:IsDataSource="True" /> 
    </UserControl.Resources> 

    <Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource ViewModel}}" Background="White"> 

     <sdk:DataGrid ItemsSource="{Binding Employees,Mode=TwoWay}" AutoGenerateColumns="False" CanUserSortColumns="True" CanUserReorderColumns="True" CanUserResizeColumns="True" GridLinesVisibility="All" Height="317" HorizontalAlignment="Left" Margin="12,136,0,0" Name="EmployeesGrid" VerticalAlignment="Top" Width="605"> 
      <sdk:DataGrid.Columns> 


<!-- snipped from brevity --> 

       <sdk:DataGridTemplateColumn Header="Status"> 
        <sdk:DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding EmployeeStatus.Description}" TextWrapping="Wrap"></TextBlock> 
         </DataTemplate> 
        </sdk:DataGridTemplateColumn.CellTemplate> 
        <sdk:DataGridTemplateColumn.CellEditingTemplate> 
         <DataTemplate> 
          <ComboBox ItemsSource="{Binding Path=EmployeeStatuses}" SelectedItem="{Binding EmployeeStatus, Mode=TwoWay}" /> 
         </DataTemplate> 
        </sdk:DataGridTemplateColumn.CellEditingTemplate> 
       </sdk:DataGridTemplateColumn> 

      </sdk:DataGrid.Columns> 
     </sdk:DataGrid> 
     <TextBlock x:Name="SearchLabel" HorizontalAlignment="Left" Margin="12,95,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="106" Height="34"><Run FontWeight="Bold" Text="Search By Name: "/><Run FontSize="9.333" Text="(Last, First)"/></TextBlock> 
     <TextBox x:Name="SearchParam" HorizontalAlignment="Left" Margin="144,101,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="162"/> 
     <Button x:Name="SearchButton" Content="Search" HorizontalAlignment="Right" Margin="0,102,242,0" VerticalAlignment="Top" Width="75" Click="SearchButton_Click"/>  


    </Grid> 
</UserControl> 

视图模型:

using System.Collections.ObjectModel; 
using SilverlightApplication1.EmployeeService; 
using SilverlightApplication1.ViewModels; 

namespace SilverlightApplication1 
{ 
    public class EmployeeDetailsViewModel : ViewModelBase 
    { 
     readonly IEmployeeServiceAgent _serviceAgent; 
     ObservableCollection<EmployeeStatus> _employeeStatuses { get; set; } 
     ObservableCollection<Employee> _employees { get; set; } 

     public EmployeeDetailsViewModel() : this(new EmployeeServiceAgent()) { } 
     public EmployeeDetailsViewModel(IEmployeeServiceAgent serviceAgent) 
     { 
      if (!IsDesignTime) 
      { 
       _serviceAgent = serviceAgent; 
       GetAllEmployees(); 
       GetEmployeeStatuses(); 
      } 

     } 

     public ObservableCollection<Employee> Employees 
     { 
      get { return _employees; } 
      set 
      { 
       if(_employees!=value) 
       { 
        _employees = value; 
        OnNotifyPropertyChanged("Employees"); 
       } 
      } 
     } 

     public ObservableCollection<EmployeeStatus> EmployeeStatuses 
     { 
      get { return _employeeStatuses; } 
      set 
      { 
       if (_employeeStatuses != value) 
       { 
        _employeeStatuses = value; 
        OnNotifyPropertyChanged("EmployeeStatuses"); 
       } 
      } 
     } 

     private void GetAllEmployees() 
     { 
      _serviceAgent.GetAll((s, e) => Employees = e.Result); 
     } 

     private void GetEmployeeStatuses() 
     { 
      _serviceAgent.GetEmployeeStatuses((s, e) => EmployeeStatuses = e.Result); 
     } 

    } 
} 

更新:

这似乎是错误的,但我想通了,如何让通过重新引用视图模型绑定工作在ItemSource绑定中:

<ComboBox ItemsSource="{Binding Source={StaticResource ViewModel},Path=EmployeeStatuses}" 
             DisplayMemberPath="Description" 
             SelectedItem="{Binding EmployeeStatus, Mode=TwoWay}" /> 

但是,我现在遇到SelectedItem未绑定的问题!我究竟做错了什么?

回答

2

这个问题是人们碰到的常见问题。当您在列的数据模板中时,您不再限制视图模型。此时您的数据上下文是EmployeeStatus对象(它没有要绑定的EmployeeStatuses属性)。

因此,要使组合框工作,可以使用ElementName = LayoutRoot将树备份到根ViewModel。

更新:这里将是你的绑定完整的语法:

{结合DataContext.EmployeeStatuses,的ElementName = LayoutRoot}

UPDATE2:其实我已经运行到这个问题,以及和有一个workaround you have to implement可以让元素名称绑定在数据网格中工作。

+1

您的意思是添加的ElementName = LayoutRoot到ComboBox的的ItemsSource?我这样做了,但ComboBox仍然没有绑定。 Rokal 2010-07-07 19:28:11

+1

科比,我试过 Rokal 2010-07-07 20:06:21

+0

尝试在上次更新的链接中使用解决方法。 – Bryant 2010-07-08 14:43:47

相关问题