2017-02-15 28 views
0

私は、項目のリストとヘッダを含むグループクラスを持っています。私のメインクラスでは、私はグループの監視可能なコレクションを持っていると私はこのようにそれを移入:選択した項目が

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があります。コントロールは、グループ名のヘッダーを配置し、そのグループ内の特定の項目のリストビューを表示する必要があります。レイアウトは完璧に機能します...しかし、問題は私がを扱うときに出ます。選択項目。基本的には、リストビューで複数のグループのうちの1つのアイテムを選択することができます。つまり、いつでも複数のアイテムを選択できます。たとえば、グループAの最初の項目を選択するとします。ただし、グループBの2番目の項目に変更します。グループBは別のリストであるため、その項目をアクティブにできますが、グループAの項目を選択解除しません。私が望むのは、この複数リストグループを単一のリストとして機能させることです。これは可能ですか?別途セットアップする必要がありますかSelectionChangedイベント?そしてもしそうなら、選択したアイテムをすべてのリストからクリアし、ユーザーが選択したものだけを表示するように、選択が変更されたことを確認するにはどうすればよいですか?

答えて

1

これは、ビューモデルクラスで処理する必要があります。

あなたはMyGroupクラスに各グループの選択したアイテムを保持し、INotifyPropertyChangedインタフェースを実装するプロパティを追加した場合、あなたはCurrentItemプロパティを設定するには、ビューモデルクラスのGroupsコレクションのCollectionChangedイベントを扱うことができるとの同じ時刻に他のグループのSelectedItemプロパティをクリアするには、このイベントハンドラでnullに設定します。

次はあなたの例です。

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)); 
    } 
} 

表示:

+0

これは完全に機能しました。徹底的な対応をありがとう! – andyopayne

関連する問題