winforms 如何遍历内部包含多个Object的对象并临时强制类型转换

qmelpv7a  于 2023-01-17  发布在  其他
关注(0)|答案(3)|浏览(127)

我有下面的代码,运行通过GroupControl,在C#中本机被称为GroupBox,我想做的是通过它内部,并根据对象是我想执行一个动作,例如:

foreach (Control item in groupControl1.Controls)
{
    MessageBox.Show(item.ToString());

    if (item is CalcEdit)
    {
        (CalcEdit)item = item.value=0
    }

    if (item is DateEdit)
    {
        (DateEdit)item = item.DateTime.now
    }
}

但是我不知道正确的方法来暂时地对对象进行等级划分,以获得它的属性,从而建立我想要的价值。
什么是暗示?

oyxsuwqo

oyxsuwqo1#

这里有一个选择:

foreach (Control item in groupControl1.Controls)
{
    MessageBox.Show(item.ToString());

    if (item is CalcEdit calcItem)
    {
        calcItem.Value = 0;
    }
    else if (item is DateEdit dateItem)
    {
        dateItem.DateTime = DateTime.Now;
    }
}

我做了一些小的调整,因为你的代码似乎没有意义,但模式匹配是重要的一部分。
您还可以执行以下操作:

foreach (var item in groupControl1.Controls.OfType<CalcEdit>())
{
    item.Value = 0;
}

foreach (var item in groupControl1.Controls.OfType<DateEdit>())
{
    item.DateTime = DateTime.Now;
}

第二个选项效率较低,因为它将整个Controls集合枚举两次,但由于项目数量非常少,因此差异微不足道。

e7arh2l6

e7arh2l62#

@jmcilhinney的答案(非常好)需要C# 7.0或更高版本。如果由于某种原因,您只能使用较早版本(缺少模式匹配),那么这个稍微麻烦一点的方法是一种替代方法:

CalcEdit calcEditItem = item as CalcEdit;
if (calcEditItem != null)
{
    calcEditItem.Value = 0;
}

DateEdit dateEditItem = item as DateEdit;
if (dateEditItem != null)
{
    dateEditItem.DateTime = DateTime.Now;
}
a11xaf1n

a11xaf1n3#

虽然确定类型和设置属性是很简单的

var control = current as TextBox;
if (control != null) control.Text = "x"
// or
if (current is TextBox) 
{
    control = (TextBox)current;
    control.Text = "x" ;
}
// or same ^^ with use pattern matching in the later c# versions

但是,这也代表了一个有趣的实现“责任链”模式的案例,但仅在您具有比仅仅设置值更复杂的逻辑的情况下

public abstract class ControlHandler
{
    private ControlHandler _nextHandler;
    
    public void AddNext(IControlHandler h)
    {
        _nextHandler = h;
    }
    
    public void SetValue(Control c, object val)
    {
        if (SetValueProtected(c, val))
            return;

        if (_nextHandler != null)
            return;
    
    }

    protected abstract bool CanSetValueProtected(Control c, object val);
} 

public class TextBoxControlHandler  : ControlHandler
{
    
    protected override bool CanSetValueProtected(Control c, object val)
    {
         if (!(c is TexBox))
             return false;
         // your value and other logic here
         // AND !! you can pass form/parent control reference here to do more
         return true;
    }
} 

public class CalcEditControlHandler  : ControlHandler
{
    
    protected override bool CanSetValueProtected(Control c, object val)
    {
         if (!(c is CalcEdit))
             return false;
         // your value and other logic here
         // AND !! you can pass form/parent control reference here to do more
         return true;
    }
} 
// ------------
// USAGE

var first = new TextBoxControlHandler();
var second = new CalcEditControlHandler(); second.AddNext(first);
// more handlers here

foreach (Control item in groupControl1.Controls)
    first.SetValue(item, value);

不过话又说回来...看看这对你来说是不是矫枉过正

相关问题