2017-02-15 107 views
0

我有一组类,它包含的项目列表和标题:选择多个列表项目

public class MyGroup {  
    public MyGroup(string _header){ 
     header = _header; 
    } 

    protected string header = ""; 
    public string Header 
    { 
     get { return header; } 
    } 

    protected List<MyGroupItem> item = new List<MyGroupItem>(); 
    public List<MyGroupItem> Item 
    { 
     get { return item; } 
    } 
} 

public class MyGroupItem {  
    public MyGroupItem(string _name, double _multiplier){ 
     name = _name; 
     multiplier = _multiplier; 
    } 

    protected double multiplier = 1.0; 

    protected string name = ""; 
    public string Name 
    { 
     get { return name; } 
    } 
} 

到目前为止好。在我的主类,我组的观察的集合,我填充它是这样的:

protected ObservableCollection<MyGroup> groups = new ObservableCollection<MyGroup>(); 
public ObservableCollection<MyGroup> Groups 
{ 
    get { return groups; } 
} 

protected MyGroupItem currentItem; 
public MyGroupItem CurrentItem 
{ 
    get { return currentItem; } 
    set 
    { 
     if (currentItem== value) return; 
     currentItem= value; 
     NotifyPropertyChanged("CurrentItem"); 
    } 
} 

.... 

var GroupA = new MyGroup("Group A"); 
GroupA.MyGroupItem.Add("Item 1", 1.0); 
Groups.Add(GroupA); 

currentItem = GroupA.MyGroupItem[0]; 

所有上述的简单显示了如何已经设置我的课和观察的名单。现在,我切换到xaml。

<ItemsControl ItemsSource="{Binding Path=Groups}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Background="Transparent" ClipToBounds="True" Orientation="Vertical"></StackPanel> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 

    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type local:MyGroup}"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path=Header}"></TextBlock> 
       <ListView ItemsSource="{Binding Path=MyGroupItem}" SelectedItem="{Binding Path=DataContext.CurrentItem, ElementName=ControlRoot}"> 
        <ListView.ItemTemplate> 
         <DataTemplate DataType="local:MyGroupItem"> 
          <TextBlock Text="{Binding Path=Name}"></TextBlock> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

所以,基本上我有一个ItemControl显示多个项目列表。控件应该为组的名称放置标题,然后显示该组中特定项目的列表视图。布局完美...但是,问题来了,当我处理选定项目。基本上,列表视图允许我在多个组中选择一个项目......这意味着我可能在任何给定时间选择多个项目。例如,假设我选择了组A中的第一个项目,但是,我将选择更改为组B中的第二个项目。因为组B是一个单独的列表,它允许我激活该项目......但它不会取消选择组A中的项目。我想要的是这个多列表组作为单个列表。这可能吗?我是否需要单独设置SelectionChanged事件?如果是的话,我该如何确定选择何时被更改,以便清除所有列表中的选定项目,并且只显示用户刚选择的正确项目?

回答

1

你应该在你的视图模型类中处理这个。

如果添加一个属性来保存每个组的MyGroup类的所选项目并实现INotifyPropertyChanged界面,你可以处理CollectionChanged事件Groups集合中的视图模型类的设置CurrentItem属性,并在同时通过在此事件处理程序中将其设置为null来清除其他组的SelectedItem属性。

下面是一个例子给你。

MyGroup.cs:

public class MyGroup : INotifyPropertyChanged 
{ 
    public MyGroup(string _header) 
    { 
     header = _header; 
    } 

    protected string header = ""; 
    public string Header 
    { 
     get { return header; } 
    } 

    protected List<MyGroupItem> item = new List<MyGroupItem>(); 
    public List<MyGroupItem> Item 
    { 
     get { return item; } 
    } 

    private MyGroupItem _item; 
    public MyGroupItem SelectedItem 
    { 
     get { return _item; } 
     set { _item = value; NotifyPropertyChanged(); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

} 

MyGroupItem.cs:

public class MyGroupItem 
{ 
    public MyGroupItem(string _name, double _multiplier) 
    { 
     name = _name; 
     multiplier = _multiplier; 
    } 

    protected double multiplier = 1.0; 

    protected string name = ""; 
    public string Name 
    { 
     get { return name; } 
    } 
} 

视图模型:

public class Window1ViewModel : INotifyPropertyChanged 
{ 
    public Window1ViewModel() 
    { 
     groups.CollectionChanged += (s, e) => 
     { 
      if (e.NewItems != null) 
      { 
       foreach (object item in e.NewItems) 
       { 
        (item as INotifyPropertyChanged).PropertyChanged 
         += new PropertyChangedEventHandler(item_PropertyChanged); 
       } 
      } 

      if (e.OldItems != null) 
      { 
       foreach (object item in e.OldItems) 
       { 
        (item as INotifyPropertyChanged).PropertyChanged 
         -= new PropertyChangedEventHandler(item_PropertyChanged); 
       } 

      }; 
     }; 

     var GroupA = new MyGroup("Group A"); 
     GroupA.Item.Add(new MyGroupItem("Item 1", 1.0)); 
     GroupA.Item.Add(new MyGroupItem("Item 2", 1.0)); 
     GroupA.Item.Add(new MyGroupItem("Item 3", 1.0)); 
     Groups.Add(GroupA); 

     var GroupB = new MyGroup("Group B"); 
     GroupB.Item.Add(new MyGroupItem("Item 1", 1.0)); 
     GroupB.Item.Add(new MyGroupItem("Item 2", 1.0)); 
     GroupB.Item.Add(new MyGroupItem("Item 3", 1.0)); 
     Groups.Add(GroupB); 

     currentItem = GroupA.Item[0]; 
    } 

    private bool _handle = true; 
    private void item_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (!_handle) 
      return; 

     MyGroup group = sender as MyGroup; 
     CurrentItem = group.SelectedItem; 

     //clear the selection in the other groups: 
     _handle = false; 
     foreach (MyGroup g in Groups) 
      if (g != group) 
       g.SelectedItem = null; 
     _handle = true; 
    } 

    protected ObservableCollection<MyGroup> groups = new ObservableCollection<MyGroup>(); 
    public ObservableCollection<MyGroup> Groups 
    { 
     get { return groups; } 
    } 

    protected MyGroupItem currentItem; 
    public MyGroupItem CurrentItem 
    { 
     get { return currentItem; } 
     set 
     { 
      if (currentItem == value) return; 
      currentItem = value; 
      NotifyPropertyChanged("CurrentItem"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

查看:

<ItemsControl ItemsSource="{Binding Path=Groups}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Background="Transparent" ClipToBounds="True" Orientation="Vertical"></StackPanel> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type local:MyGroup}"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path=Header}"></TextBlock> 
       <ListView ItemsSource="{Binding Path=Item}" 
            SelectedItem="{Binding SelectedItem}"> 
        <ListView.ItemTemplate> 
         <DataTemplate DataType="local:MyGroupItem"> 
          <TextBlock Text="{Binding Path=Name}"></TextBlock> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+0

这工作完美!感谢彻底的回应! – andyopayne

相关问题