【解决方案】ItemsControl删除元素,但仍然显示它们

例如一个选手机号的程序,有一系列手机号可选。有些手机号已经被人选走了,列表仍然显示它们,但多加一条删除线,如图。

如图,淡色的、被线划掉的就是已经被选走的。这样的功能该如何实现呢?


具体要求

外界可以把这种控件视为ListBox,加元素就是Items.Add,删元素就是Items.Remove。外界不应去关心如何“假删”。

此控件的应用范围应更为广泛,允许用模板来自定义被删除后的显示。

另外,出于个人爱好,此控件内部应尽量简单,少写代码;不重复发明微软专家已经发明的轮子。

实现

 class RetainRemovedListBox : ListBox
    {
        public RetainRemovedListBox()
        {
            ((INotifyCollectionChanged)Items).CollectionChanged += Class1_CollectionChanged;
        }

        void Class1_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                Items.Insert(e.OldStartingIndex, e.OldItems[0]);
                EventHandler itemContainerGeneratorOnStatusChanged = null;
                itemContainerGeneratorOnStatusChanged = (sender1, e1) =>
                        {
                            if (ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
                            {
                                ItemContainerGenerator.StatusChanged -= itemContainerGeneratorOnStatusChanged;

                                IsRemovedListBoxItem lbi = (IsRemovedListBoxItem)ItemContainerGenerator.ContainerFromItem(e.OldItems[0]);
                                lbi.IsRemoved = true;
                                lbi.IsEnabled = false;
                            }
                        };
                ItemContainerGenerator.StatusChanged += itemContainerGeneratorOnStatusChanged;
            }

        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new IsRemovedListBoxItem();
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is IsRemovedListBoxItem;
        }


    }

    class IsRemovedListBoxItem : ListBoxItem
    {
        public static readonly DependencyProperty IsRemovedProperty = 
            DependencyProperty.Register("IsRemoved", typeof(bool), typeof(IsRemovedListBoxItem), new FrameworkPropertyMetadata(false));


        public bool IsRemoved
        {
            get { return (bool)GetValue(IsRemovedProperty); }
            set { SetValue(IsRemovedProperty, value); }
        }
    }

简单解释一下。所谓删除元素,其实删完以后又加了回去,但给它的Container做了记号,于是能够呈现“被删除”的外观。

GetContainerForItemOverride的父类实现是new ListBoxItem。

如果需要真正清除被删除的元素,可以在RetainRemovedListBox里面添加一个方法,对Items里每个元素调用ItemContainerGenerator.ContainerFromItem,检查IsRemoved,然后再删。当然了,Class1_CollectionChanged又会把这个元素添加回去。我相信,勤劳勇敢的中国人能自己解决好这个问题的。

用法



    
        

        private void Button2_Click(object sender, RoutedEventArgs e)
        {
            myItemsControl.Items.Remove(myItemsControl.SelectedItem);
        }

填充靓号的代码属技术专利,就不给了。:)

你可能感兴趣的:(C#,解决方案,软件发布)