如何制作像RadioButton这样的布尔属性?你知道,就像RadioButton一样,只能选择一个吗?
如下图所示。
当我将一个Employee IsResponsiblePerson
设置为true时,它应该将所有其他人设置为false。不使用循环。
var list = new ObservableCollection<Employee>();
public class Employee
{
public string Name{get;set;}
public string Surname{get;set;}
public bool IsResponsiblePerson{get;set;}
}
答案 0 :(得分:5)
如果我不想使用循环,我可能会做什么,就像Lasse V. Karlsen在评论中所说的那样,存储着&#34; ResponsiblePerson&#34;在另一个属性:
static string ResponsiblePerson {get;set;}
将IsResponsiblePerson
属性更改为以下内容:
public bool IsResponsiblePerson
{
get
{
return this.Name == ResponsiblePerson;
}
set
{
if (value)
{
ResponsiblePerson = this.Name;
}
else
{
if (this.Name == ResponsiblePerson)
{
ResponsiblePerson = "";
}
}
}
}
示例代码:
List<Employee> employees = new List<Employee>() { new Employee() { Name = "name1" },
new Employee() { Name = "name2" },
new Employee() { Name = "name3" } };
Employee emp1 = employees.Where(x => x.Name == "name1").First();
emp1.IsResponsiblePerson = true;
Employee emp2 = employees.Where(x => x.Name == "name2").First();
emp2.IsResponsiblePerson = true;
foreach (Employee e in employees)
{
Console.WriteLine(e.IsResponsiblePerson); //false true false
}
我制作了一个DotNetFiddle示例here
答案 1 :(得分:4)
这是继承自List<Employee>
或ObservableCollection<Employee>
的新集合类型的理想用例。在那里你可以封装整个逻辑。
在您通过自定义事件使Employee
类更加智能化之前,集合类想知道属性IsResponsiblePerson
何时设置为true
,因为它必须更改老责任。例如:
public class Employee
{
public string Name { get; set; }
public string Surname { get; set; }
public event EventHandler ResponsiblePersonChanged;
private bool _isResponsiblePerson;
public bool IsResponsiblePerson
{
get => _isResponsiblePerson;
set
{
_isResponsiblePerson = value;
if (_isResponsiblePerson)
{
ResponsiblePersonChanged?.Invoke(this, EventArgs.Empty);
}
}
}
}
现在集合类可以像下面这样实现,它处理每个Employee
ResponsiblePersonChanged
事件:
public class EmployeeCollection : ObservableCollection<Employee>
{
public Employee Responsible { get; private set; }
public EmployeeCollection():base(){}
public EmployeeCollection(IEnumerable<Employee> employees) : base()
{
foreach (Employee e in employees)
{
if (e.IsResponsiblePerson)
{
if(Responsible != null)
throw new ArgumentException("Multiple responsible employees aren't allowed", nameof(employees));
Responsible = e;
}
base.Add(e);
}
}
public new void Add(Employee emp)
{
base.Add(emp);
if (emp.IsResponsiblePerson)
{
MakeResponsible(emp);
}
emp.ResponsiblePersonChanged -= ResponsibleChanged;
emp.ResponsiblePersonChanged += ResponsibleChanged;
}
private void ResponsibleChanged(Object sender, EventArgs e)
{
MakeResponsible(sender as Employee);
}
private void MakeResponsible(Employee employee)
{
if(!employee.IsResponsiblePerson)
throw new ArgumentException("Employee is not responsible but should be", nameof(employee));
if (Responsible != null && !Responsible.Equals(employee))
Responsible.IsResponsiblePerson = false;
Responsible = employee;
}
}
一个例子:
var list = new EmployeeCollection();
list.Add(new Employee { Name = "1", IsResponsiblePerson = true });
list.Add(new Employee { Name = "2", IsResponsiblePerson = false });
list.Add(new Employee { Name = "3", IsResponsiblePerson = false });
list.Add(new Employee { Name = "4", IsResponsiblePerson = false });
list.Add(new Employee { Name = "5", IsResponsiblePerson = false });
list.Last().IsResponsiblePerson = true; // now the first employee's IsResponsiblePerson is set to false
答案 2 :(得分:1)
不幸的是,你的例子接近于能够处理&#34;更改&#34;布尔值的事件,但不完全。您的示例仅允许处理对集合的更改,而不是更改其内部元素之一。
为此,您需要实施INotifyPropertyChanged
,here's an example。虽然记在那里有一百万个通知机制,所以对它进行一些研究。
要回答您的问题(&#34;如果元素的属性发生变化,我如何更新集合的其他成员&#34;)您需要处理特定属性的已更改事件,在您的情况下IsResponsiblePerson
。然后,在该处理程序中,您可以使用Linq(内部使用循环),但无论发生什么,您将始终必须对整个列表执行操作(可能可能提前中断循环)以实现您的操作。问。
要研究的另一个概念是ObservableObject
,与INotifyPropertyChanged
密切相关。Here's the doc on it