1

我想出了这段代码,我认为它相当聪明(要求是如果选择的日期是过去的,则 TextBoxes 应该是只读的,否则(今天的日期或未来的日期)它们应该是可编辑的):

bool? setReadOnly = null;

if (SelectedDateIsInThePast() && (!currentlyReadOnly)) {
    setReadOnly = true;
} else if (!SelectedDateIsInThePast() && (currentlyReadOnly)) {
    setReadOnly = false;
}
if (setReadOnlyToTrue.HasValue) {
    foreach (Control ctrl in tableLayoutPanelPlatypus.Controls) {
        if (ctrl is TextBox) {
            tb = (TextBox)ctrl;
            tb.ReadOnly = setReadOnlyToTrue.Value;
        }
    }
}

...但在我的伙伴中发现可空布尔值是“不受欢迎的数据类型”。

是否有一种简单的方法来做同样的事情(如果需要更改只读值,则仅循环通过控件?)。当然,我可以简单地设置它们,而不管它们是否需要这样设置:

if (SelectedDateIsInThePast()) {
    setReadOnly = true;
} else {
    setReadOnly = false;
}
foreach (Control ctrl in tableLayoutPanelPlatypus.Controls) {
    if (ctrl is TextBox) {
        tb = (TextBox)ctrl;
        tb.ReadOnly = setReadOnly;
    }
}

...但我不喜欢执行模拟操作,如果可以合理地避免它们的话。

4

5 回答 5

3

将循环分解为一个方法,并且仅在您设置的情况下调用该方法setReadOnly

if (SelectedDateIsInThePast() && (!currentlyReadOnly)) {
    SetReadOnly(true);
} else if (!SelectedDateIsInThePast() && (currentlyReadOnly)) {
    SetReadOnly(false);
}
于 2012-05-16T16:17:16.553 回答
1

您可以使用|=&=和两个不可为空的布尔值来实现相同的要求:

bool forceReadOnly = SelectedDateIsInThePast() && (!currentlyReadOnly);
bool clearReadOnly = !(!SelectedDateIsInThePast() && (currentlyReadOnly));

foreach (Control ctrl in tableLayoutPanelPlatypus.Controls) {
    if (ctrl is TextBox) {
        tb = (TextBox)ctrl;
        tb.ReadOnly |= forceReadOnly;
        tb.ReadOnly &= clearReadOnly;
    }
}
于 2012-05-16T16:15:55.673 回答
1

我认为可以为空的布尔值很好......但另一种方式是:

public enum ControlState
{
    Unknown = 0,
    DateInPast,
    DateInFuture
}

....

var state = ControlState.Unknown;

if (SelectedDateIsInThePast() && (!currentlyReadOnly)) {
    state = ControlState.DateInPast;
} else if (!SelectedDateIsInThePast() && (currentlyReadOnly)) {
    state = ControlState.DateInFuture;
}
if (state != ControlState.Unknown) {
    foreach (Control ctrl in tableLayoutPanelPlatypus.Controls) {
        if (ctrl is TextBox) {
            tb = (TextBox)ctrl;
            tb.ReadOnly = setReadOnlyToTrue.Value;
        }
    }
}
于 2012-05-16T16:16:37.770 回答
1

使用具有三个独立的、有意义的状态的枚举?

enum ShouldSetState
{
    No, 
    SetReadOnly,
    SetReadable
}

然后做

ShouldSetState setState = ShouldSetState.No;

if (SelectedDateIsInThePast() && (!currentlyReadOnly)) {
    setState = ShouldSetState.SetReadOnly;
} else if (!SelectedDateIsInThePast() && (currentlyReadOnly)) {
    setState = ShouldSetState.SetReadable;
}
if (setState != ShouldSetState.No) {
    foreach (Control ctrl in tableLayoutPanelPlatypus.Controls) {
        if (ctrl is TextBox) {
            tb = (TextBox)ctrl;
            tb.ReadOnly = setState == ShouldSetState.SetReadOnly;
        }
    }
}
于 2012-05-16T16:17:23.677 回答
0

您的代码可以在不使用可为空的 bool 的情况下变得更简洁:

bool inThePast = SelectedDateIsInThePast();
if (currentlyReadOnly != inThePast )
{
    currentlyReadOnly = inThePast;
    foreach(var tb in tableLayoutPanelPlatypus.Controls.OfType<TextBox>())
        tb.ReadOnly = currentlyReadOnly;
}

此外,如果您必须进行大量此类 UI 操作,您可能会考虑数据绑定

于 2012-05-16T16:37:01.077 回答