首先说说需求,有多种不同类型的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也不常用,但对内存有一个良好的规划,是一个程序员基本的素养。

 public class IsSelectedClass : INotifyPropertyChanged
{
protected bool isSelected;
public virtual bool IsSelected
{
get =>isSelected;
set
{
isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} public void SetSelectedTrue()
{
this.isSelected = true;
}
} public class RadioGroupList<T> where T : IsSelectedClass
{
List<T> list = new List<T>(); public void AddRadioSelector(T t)
{
list.Add(t);
t.PropertyChanged += TSelectedPropertyChangedEventHandler; } private void TSelectedPropertyChangedEventHandler(object sender, PropertyChangedEventArgs e)
{
var t = sender as IsSelectedClass;
if (e.PropertyName == nameof(t.IsSelected))
{
if (t.IsSelected)
{
for (int i = ; i < list.Count; i++)
{
list[i].IsSelected = false;
}
t.SetSelectedTrue();
}
}
} public void RemoveSelector(T t)
{
if (list.Contains(t))
{
list.Remove(t);
t.PropertyChanged -= TSelectedPropertyChangedEventHandler;
}
}
}

关键代码

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 = ;//控制循环生成对象的数目 for (int i = ; i < tcount; i++)
{
islist.AddRadioSelector(new IsSelectedClass());
} islist[].IsSelected = true; islist[].IsSelected = true; islist[].IsSelected = true; islist[].IsSelected = true; for (int i = ; i < tcount; i++)
{
Console.WriteLine($"{i}={islist[i].IsSelected}");
}
}

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

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

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

RadioGroupList<T>

C#使用List实现类似RadioButtonGroup的单选功能的更多相关文章

  1. 自定义GrildView实现单选功能

    首先看实现功能截图,这是一个自定义Dialog,并且里面内容由GrildView 绑定数据源,实现类似单选功能. 首先自定义Dialog,绑定数据源 自定义Dialog弹出框大小方法 最主要实现的就是 ...

  2. C# winform项目中ListView控件使用CheckBoxes属性实现单选功能

    C# winform项目中ListView控件使用CheckBoxes属性实现单选功能 在做项目时需要使用ListView控件的CheckBoxes属性显示,还要在点击行时自动选中CheckBoxes ...

  3. ASP.NET js控制treeview中的checkbox实现单选功能

    ASP.NET js控制treeview中的checkbox实现单选功能 function OnTreeNodeChecked() { var element = window.event.srcEl ...

  4. 实现类似mysql group_concat的功能

    实现类似mysql group_concat的功能 SELECT SG.Id ,SG.GroupName ,HostNames = STUFF((SELECT ',' + SH.[HostName] ...

  5. 利用原生JS实现类似浏览器查找高亮功能(转载)

    利用原生JS实现类似浏览器查找高亮功能 在完成 Navify 时,增加一个类似浏览器ctrl+f查找并该高亮的功能,在此进行一点总结: 需求 在.content中有许多.box,需要在.box中找出搜 ...

  6. WPF中类似使用tab键功能,可以向上向下定位

    原文:WPF中类似使用tab键功能,可以向上向下定位 private void tbYyrs_KeyUp(object sender, KeyEventArgs e) { UIElement elem ...

  7. iView的tree组件实现单选功能

    iView中的树组件有复选框可以多选,但是目前还没有提供单选框的模式,不显示复选框可以提供高亮单选的模式,但是再次点击就被取消了,没有实现真正的单选: tree 的属性配置中 multiple 是否支 ...

  8. 通过Java SE 7自带的监控服务(WatchService API)实现类似.NET FileWatcher的功能

    Java SE 7 Tutorial中增加了一个监控目录变更情况的示例,用于介绍其新发布的WatchService API. 但对于用惯了.NET FileWatcher的用户而言,如果用于项目我认为 ...

  9. mysql定时执行及延时执行,实现类似sql server waitfor功能

    熟悉SQL Server的人都知道,它有一个很有用的功能,waitfor time和waitfor delay,前者表示在某个时间执行,后者表示等待多长时间执行.在我们测试功能和定时执行的时候特别有用 ...

随机推荐

  1. zabbix升级遇到连接不上数据库的问题

    问题 迁移zabbix-server端时,原来是4.0版本,现在为4.2版本,遇到如下问题       解决办法 update dbversion set mandatory=;        

  2. repo/repo init-解决同步源码Cannot get http://gerrit.googlesource.com/git-repo/clone.bundle

    以下转自:http://www.cnblogs.com/dinphy/p/5669384.html 问题: fatal: Cannot get https://gerrit.googlesource. ...

  3. Linux基础入门-目录结构及文件基本操作

    一.Linux的目录结构: Windows是以存储介质为主的,主要以盘符及分区来实现文件的管理,然后之下才是目录.但Linux的磁盘从逻辑上来说是挂载在目录上的,每个目录不仅能使用本地磁盘分区的文件系 ...

  4. streamsets

    streamstes用户指南: https://streamsets.com/documentation/datacollector/latest/help/index.html#datacollec ...

  5. docker的windows环境设置

    1.下载docker-install.exe安装VirtualBox.Git.Boot2Docker for Windows 2.设置环境变量,启动boot2docker Core Linux. 可以 ...

  6. Optaplanner终于支持多线程并行运行 - Multithreaded incremental solving

    Optaplanner 7.9.0.Final之前,启动引擎开始对一个Problem进行规划的时候,只能是单线程进行的.也就是说,当引擎对每一个possible solution进行分数计算的过程中, ...

  7. 用openssl为EAP-TLS生成证书(CA证书,服务器证书,用户证书)

    用openssl为EAP-TLS生成证书(CA证书,服务器证书,用户证书) 来源: https://www.cnblogs.com/osnosn/p/10597897.html 来自osnosn的博客 ...

  8. Hadoop 管理工具HUE配置-初始配置

    1 界面换成中文 默认是英文的,可以修改为中文 1.修改配置文件settings.pynano hue/desktop/core/src/desktop/settings.py LANGUAGE_CO ...

  9. 微信小程序云函数Windows下安装wx-server-sdk

    第一次上传部署云函数时,会提示这个,建议在这之前先安装一下node.js. https://nodejs.org/en/ 下载nodejs,然后直接安装,在cmd控制台输入node -v和npm -v ...

  10. linux中.nfsxxxx引起的文件无法删除

    一个linux系统中的某个文件夹无法删除,使用ls -al查看有1个.nfsxxxx的文件无法删除. 使用lsof +D /filepath/,查看到文件被一个进程一直占用. 再使用ps -aux | ...