码迷,mamicode.com
首页 > Windows程序 > 详细

C#使用List实现类似RadioButtonGroup的单选功能

时间:2017-10-02 14:27:47      阅读:333      评论:0      收藏:0      [点我收藏+]

标签:isl   set   get   准备   call   play   程序   存储   输出   

首先说说需求,有多种不同类型的UserControl用于以不同的方式显示数据,想通过在另一个view中实现某种点击选中按钮后,在数据显示view中,只让被逻辑关联的UserControl显示(Visiable),其他UserControl全部折叠(Collasped)起来。这种方式就类似于几个控件绑定到一组RadioButtonGroup中,哪个RadioButton被选中了,就显示哪部分内容。

虽然我知道有种修改template的方式,应该可以做到,但我还没深入学习到这部分。于是想了个别的招。 

技术分享

因为是在不同的View上,如此一来,就不能简单地通过绑定到元素的IsSelected->Visilibity的方式来实现。

那么就自己实现一个类似于RadioButtonGroup的功能。

1.首先准备一个类,用于和我的UserControl的Visilibity属性绑定。

public class IsSelectedClass
{
    protected bool isSelected;
    public bool IsSelected 
  {     
    get=>isSelected; set { isSelected = value; OnPropertyChanged(nameof(IsSelected)); } } }

2.准备一个GroupList,用于存储我们加入(Add)的IsSelectedCalss对象

List<IsSelectedCalss> list = new List<IsSelectedCalss>();

3.为了有更好的扩展性和兼容性,接下来将IsSelectedCalss和List<IsSelectedCalss>重新封装为泛型形式

并且,因为IsSelected属性与UserControl的Visibility属性进行绑定,所以要实现INotifyPropertyChanged接口。

我们将RadioGroupList类视为RadioButtonGroup类,往RadioGroupList对象中添加的是继承自IsSelectedClass类的对象。

并且在将IsSelectedClass类对象添加进List的时候,订阅其PropertyChanged事件,这样我们可以在该对象的IsSelected属性值改变时收到通知,然后再处理List中的其他IsSelectedClass对象。

记得在Remove掉该对象时,要取消订阅该事件。即使这对性能影响不大,而且Remove也不常用,但对内存有一个良好的规划,是一个程序员基本的素养。

技术分享
 1 public class IsSelectedClass : INotifyPropertyChanged
 2     {
 3         protected bool isSelected;
 4         public virtual bool IsSelected
 5         {
 6             get =>isSelected;
 7             set
 8             {
 9                 isSelected = value;
10                 OnPropertyChanged(nameof(IsSelected));
11             }
12         }
13         public event PropertyChangedEventHandler PropertyChanged;
14 
15         [NotifyPropertyChangedInvocator]
16         protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
17         {
18             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
19         }
20 
21         public void SetSelectedTrue()
22         {
23             this.isSelected = true;
24         }
25     }
26 
27     public class RadioGroupList<T> where T : IsSelectedClass
28     {
29         List<T> list = new List<T>();
30 
31         public void AddRadioSelector(T t)
32         {
33             list.Add(t);
34             t.PropertyChanged += TSelectedPropertyChangedEventHandler;
35             
36         }
37 
38         private void TSelectedPropertyChangedEventHandler(object sender, PropertyChangedEventArgs e)
39         {
40             var t = sender as IsSelectedClass;
41             if (e.PropertyName == nameof(t.IsSelected))
42             {
43                 if (t.IsSelected)
44                 {
45                     for (int i = 0; i < list.Count; i++)
46                     {
47                         list[i].IsSelected = false;
48                     }
49                     t.SetSelectedTrue();
50                 }
51             }
52         }
53 
54         public void RemoveSelector(T t)
55         {
56             if (list.Contains(t))
57             {
58                 list.Remove(t);
59                 t.PropertyChanged -= TSelectedPropertyChangedEventHandler;
60             }
61         }
62     }
关键代码

4.为了改进RadioGroupList<T>类的使用,添加几个类似于List的常用方法和索引器。

        public void AddRangeSelector(T[] t)
        {
            foreach (var VARIABLE in t)
            {
                AddRadioSelector(VARIABLE);
            }
        }

        public void Clear()
        {
            foreach (var VARIABLE in list)
            {
                VARIABLE.PropertyChanged -= TSelectedPropertyChangedEventHandler;
            }
            list.Clear();
        }

        public T this[int index] => list[index];

5.简单测试性能

因为重复遍历了List中的元素两次,所以,我生成了200个对象来测试其性能,看看这种做法会不会卡死界面。

        public ShellViewModel()//构造函数,没什么好说的
        {            
            RadioGroupList<IsSelectedClass> islist = new RadioGroupList<IsSelectedClass>();

            int tcount = 200;//控制循环生成对象的数目

            for (int i = 0; i < tcount; i++)
            {
                islist.AddRadioSelector(new IsSelectedClass());
            }

            islist[110].IsSelected = true;

            islist[111].IsSelected = true;

            islist[138].IsSelected = true;

            islist[198].IsSelected = true;

            for (int i = 0; i < tcount; i++)
            {
                Console.WriteLine($"{i}={islist[i].IsSelected}");
            }
        }

最终的输出结果是,只有索引为198的值为True,其他全为False。而且程序执行得很快,几乎是启动的时候就显示出来了。

没用Timer测试,是因为,这个是给控件用的,我的控件最多也不超过10个,所以性能上足够用了。

虽然这个功能很简单,但我作为一个小菜鸟,还是蛮开心的。欢迎大家多多留言交流~

RadioGroupList<T>

C#使用List实现类似RadioButtonGroup的单选功能

标签:isl   set   get   准备   call   play   程序   存储   输出   

原文地址:http://www.cnblogs.com/wingsziye/p/7620040.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!