仅在一个对象

时间:2017-09-07 10:49:33

标签: c#

如何制作像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;}
}

3 个答案:

答案 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;布尔值的事件,但不完全。您的示例仅允许处理对集合的更改,而不是更改其内部元素之一。

为此,您需要实施INotifyPropertyChangedhere's an example。虽然记在那里有一百万个通知机制,所以对它进行一些研究。

要回答您的问题(&#34;如果元素的属性发生变化,我如何更新集合的其他成员&#34;)您需要处理特定属性的已更改事件,在您的情况下IsResponsiblePerson。然后,在该处理程序中,您可以使用Linq(内部使用循环),但无论发生什么,您将始终必须对整个列表执行操作(可能可能提前中断循环)以实现您的操作。问。

要研究的另一个概念是ObservableObject,与INotifyPropertyChanged密切相关。Here's the doc on it