void onListKeyUp(KeyEventArgs args)
 {
     if (KeyboardHelper.IsKeyPressed(ModifierKeys.Control) && args.Key == Key.A)
     {
         if (Selection.Items.Count() == Items.Count())
         {
             SelectedItemIDs.Clear();
         }
         else
         {
             SelectedItemIDs.AddRange(Items.Select(Items => Items.Item.ItemId));
         }
     }
 }
        void onItemClicked(ItemClickedEventArgs args)
        {
            var curItem        = args.Item;
            var prevItem       = previouslyClickedItem;
            var isStrgPressed  = KeyboardHelper.IsKeyPressed(ModifierKeys.Control);
            var isShiftPressed = KeyboardHelper.IsKeyPressed(ModifierKeys.Shift);
            var isAltPressed   = KeyboardHelper.IsKeyPressed(ModifierKeys.Alt);

            if (isAltPressed)
            {
                return;
            }
            if (isStrgPressed)
            {
                if (curItem.IsSelected)
                {
                    SelectedItemIDs.Remove(curItem.Item.ItemId);
                }
                else
                {
                    SelectedItemIDs.Add(curItem.Item.ItemId);
                }
            }
            else if (isShiftPressed)
            {
                var section = this.Items.Subsection(curItem, prevItem);

                if (section.All(item => item.IsSelected))
                {
                    SelectedItemIDs.RemoveMany(section.Select(item => item.Item.ItemId));
                }
                else
                {
                    SelectedItemIDs.AddRange(section.Select(item => item.Item.ItemId).Except(this.SelectedItemIDs.Items));
                }
            }
            else
            {
                if (SelectedItemIDs.Count == 1 && SelectedItemIDs.Items.Contains(curItem.Item.ItemId))
                {
                    return;
                }
                this.SelectedItemIDs.Clear();
                SelectedItemIDs.Add(curItem.Item.ItemId);
            }
            previouslyClickedItem = curItem;
        }
        public ItemListViewModel(
            IItemService itemService,
            IInjectionProviderService injectionProviderService)
        {
            this._itemService = itemService ?? throw new NullReferenceException("got no itemService");
            this._injectionProviderService = injectionProviderService ?? throw new NullReferenceException("got no itemservice");

            this.DeselectAllCommand = new RelayCommand(
                _ => this.SelectedItemIDs.Clear(),
                _ => this.SelectedItemIDs.Items.Any());

            this.ItemClickedCommand = new RelayCommand(onItemClicked);

            this.ListKeyUpCommand = new RelayCommand(onListKeyUp);

            DragCommand = new RelayCommand(sender =>
            {
                if (KeyboardHelper.IsKeyPressed(ModifierKeys.Alt))
                {
                    itemDrag(sender as DependencyObject);
                }
            });

            this._injectionProviderService.Provider.Subscribe(
                (provider) =>
            {
                if (provider == null)
                {
                    throw new InvalidOperationException("provider is null");
                }
                #region list assembly
                var itemList = this._itemService
                               .GetExtended()
                               .Connect()
                               .Filter(FilterChanges)
                               .TakeUntil(destroy);

                var selectionList =
                    itemList.Transform(item => new ItemSelectionInfo(item, this, DragCommand))
                    .DisposeMany();

                var _selection =
                    SelectedItemIDs.Connect()
                    .AddKey(id => id)
                    .LeftJoin(
                        itemList,
                        item => item.ItemId,
                        (id, item) => new { id, item })
                    .RemoveKey();


                Selection =
                    _selection
                    .Filter(x => x.item.HasValue)
                    .Transform(x => x.item.Value)
                    .AsObservableList();


                _selection
                .Filter(x => !x.item.HasValue)
                .ToCollection()
                .Subscribe(col =>
                {
                    if (col.Any())
                    {
                        SelectedItemIDs.RemoveMany(col.Select(x => x.id));
                    }
                });

                selectionList
                .Sort(item => item.Item.Name)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Do(_ => this.Disconnected = true)
                .Bind(out _items)
                .Do(_ => this.Disconnected = false)
                .Subscribe();
                #endregion
            });
        }