ListView中的MVVM分组项

时间:2010-11-21 09:39:39

标签: c# wpf listview mvvm

我无法理解我做错了什么。我想在listView中对项目进行分组。 结果我想看到类似的东西:

enter image description here

它使用的是MVVM模式。这是我的XAML代码。

<CollectionViewSource x:Key="EmploeeGroup"                               
                      Source="{Binding Path=AllEmploees}">
  <CollectionViewSource.GroupDescriptions>
    <PropertyGroupDescription PropertyName="FirstName" />
  </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

<ListView AlternationCount="2" 
          DataContext="{StaticResource EmploeeGroup}"
          ItemsSource="{Binding IsAsync=True}" Padding="0,0,0,10">
  <ListView.GroupStyle>
    <GroupStyle>
      <GroupStyle.ContainerStyle>
        <Style TargetType="{x:Type GroupItem}">
          <Setter Property="Margin" Value="0,0,0,5"/>
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="{x:Type GroupItem}">
                <Expander IsExpanded="True" BorderBrush="#FFA4B97F" 
                                            BorderThickness="0,0,0,1">
                  <Expander.Header>
                    <DockPanel>
                      <TextBlock FontWeight="Bold"
                                 Text="Name: "/>
                      <TextBlock FontWeight="Bold"
                                 Text="{Binding Path=FirstName}"/>
                    </DockPanel>
                  </Expander.Header>
                  <Expander.Content>
                    <ItemsPresenter />
                  </Expander.Content>
                </Expander>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </GroupStyle.ContainerStyle>
    </GroupStyle>
  </ListView.GroupStyle>
  <ListView.View>
    <GridView>
      <GridViewColumn Width="150"
                      Header="FirstName"
                      DisplayMemberBinding="{Binding Path=FirstName}"/>
      <GridViewColumn Width="150"
                      Header="LastName"
                      DisplayMemberBinding="{Binding Path=LastName}"/>
    </GridView>
  </ListView.View>
</ListView>

这是我的 EmploeeListViewModel.cs

public class EmploeeListViewModel: ViewModelBase
{
  readonly EmploeeRepository _emploeeRepository;

  private ObservableCollection<EmploeeViewModel> _allmpl;
  public ObservableCollection<EmploeeViewModel> AllEmploees
  {
    get
    {
      if (_allmpl == null)
      {
        _allmpl = new ObservableCollection<EmploeeViewModel>();
        CreateAllEmploee();
      }
      return _allmpl;
    }
  }

  public EmploeeListViewModel(EmploeeRepository emploeeRepository)
  {
    if (emploeeRepository == null)
      throw new ArgumentNullException("emploeeRepository");

    _emploeeRepository = emploeeRepository;
    _emploeeRepository.EmploeeAdded += this.OnEmploeeAddedToRepository;
  }

 private void CreateAllEmploee()
 {
   List<EmploeeViewModel> all =
                (from emploee in _emploeeRepository.GetEmploees()
                 select new EmploeeViewModel(emploee)).ToList();
   foreach (EmploeeViewModel evm in all)
   {
     evm.PropertyChanged += this.OnEmploeeViewModelPropertyChanged;
     AllEmploees.Add(evm);
   }
   this.AllEmploees.CollectionChanged += this.OnCollectionChanged;
 }

 //this.OnCollectionChanged;
 //this.OnEmploeeViewModelPropertyChanged;
}

EmploeeViewModel.cs

public class EmploeeViewModel : ViewModelBase
{
  #region Fields
    Emploee _emploee;
    bool _isSelected;
  #endregion

  #region Constructor
    public EmploeeViewModel(Emploee emploee)
    {
      if (emploee == null)
        throw new ArgumentNullException("emploee");
      this._emploee = emploee;
    }
  #endregion

  #region Emploee Properties
    public bool IsSelected
    {
      get { return _isSelected; }
      set
      {
        if (value == _isSelected)
          return;

        _isSelected = value;
        base.OnPropertyChanged("IsSelected");
      }
    }

    public string FirstName
    {
      get { return _emploee.FirstName; }
      set
      {
        if (value == _emploee.FirstName)
          return;
        _emploee.FirstName = value;
        base.OnPropertyChanged("FirstName");
      }
    }

    public string LastName
    {
      get { return _emploee.LastName; }
      set
      {
        if (value == _emploee.LastName)
          return;
        _emploee.LastName = value;
        base.OnPropertyChanged("LastName");
      }
    }
  #endregion
}
  • 为什么我不能绑定“FirstName” 使用Expander.Header的属性 TextBlock的?
  • 为什么我对象类型为
    MS.Internal.Data.CollectionViewGroupInternal 在Expander.Header里面(如果我在里面写的 Expander.Header 文本= “{结合}”)&GT;

我该怎么办?    更改我的XAML或.CS代码以生成    these results

2 个答案:

答案 0 :(得分:22)

我自己找到了这个问题的答案。

发送到转换器的对象的类型为:MS.Internal.Data.CollectionViewGroupInternal。

主要原因是使用“Name”来数据绑定组名只是因为它是CollectionViewGroupInternal中包含当前“组集合”所具有的名称的属性(根据您指定的GroupDescription)。

不重要什么是PropertyGroupDescription中的GropertyName。 您必须始终在GroupStyle容器中使用{Binding Path = Name}。

我必须在我的XAML中只更改一个字符串。

自:

<TextBlock FontWeight="Bold" Text="{Binding Path=FirstName}"/>

要:

<TextBlock FontWeight="Bold" Text="{Binding Path=Name}"/>

答案 1 :(得分:0)

只是遇到了有关“名称/名字”绑定问题的相同问题,并在这里找到了我的项目的解决方案: Grouping ListView WPF

简而言之,通过Expander-Tag,您可以将DataContext设置为“ {Binding Items}”。之后,您可以使用原始属性名称。