最初,我有以下内容:
[Flags]
public enum QueryFlag
{
None = 0x00,
CustomerID = 0x01,
SalesPerson = 0x02,
OrderDate = 0x04
}
选中/取消选中复选框后,我会添加/删除以下标志:
QueryFlag qflag;
我的想法 - 当用户单击“搜索”按钮时,我将迭代qflag
中设置的实际标志,以修改LINQ to Sql中的.Where
子句。但是,Enum.GetValues(qflag.GetType())
将返回QueryFlag本身的所有值。没用。
我的解决方案:
class myForm : Form
{
List<QueryFlag> qflag = new List<QueryFlag>();
private void chkOrderDate_CheckedChanged(object sender, EventArgs e)
{
if (chkOrderDate.Checked && !qflags.Contains(QueryFlag.OrderDate))
qflags.Add(QueryFlag.OrderDate);
else
qflags.Remove(QueryFlag.OrderDate);
}
private void cmdSearch_Click(object sender, EventArgs e)
{
if (qflags.Count == 0)
{
rtfLog.AppendText("\nNo search criteria selected.");
return;
}
foreach (QueryFlag flag in qflag)
{
rtfLog.AppendText(string.Format("\nSearching {0}", flag.ToString()));
// add switch for flag value
}
}
}
public enum QueryFlag
{
CustomerID,
SalesPerson,
OrderDate
}
我有3个复选框,这对此没有任何问题。但我想知道是否有更好的方法来执行此迭代。
答案 0 :(得分:1)
你原来的方式是正确的;你只是被Enum.GetValues
方法搞砸了。此方法返回特定enum
类型的每个定义值,是。所以你做这个是检查特定的 enum
值的每个定义的值,看看是否设置了定义的值你的价值。
也就是说,你应该这样做:
private void chkOrderDate_CheckedChanged(object sender, EventArgs e)
{
if (chkOrderDate.Checked)
{
qFlag |= QueryFlag.OrderDate;
}
else
{
qFlag &= (~QueryFlag.OrderDate);
}
}
...同样适用于其他CheckBoxes。然后,当您想要枚举您设置的标志时:
static IEnumerable<QueryFlag> GetFlags(QueryFlag flags)
{
foreach (QueryFlag flag in Enum.GetValues(typeof(QueryFlag)))
{
// Presumably you don't want to include None.
if (flag == QueryFlag.None)
{
continue;
}
if ((flags & flag) == flag)
{
yield return flag;
}
}
}
事实上,您甚至可以将上述内容抽象为所有enum
类型的便捷扩展方法:
public static class FlagsHelper
{
// This is not exactly perfect, as it allows you to call GetFlags on any
// struct type, which will throw an exception at runtime if the type isn't
// an enum.
public static IEnumerable<TEnum> GetFlags<TEnum>(this TEnum flags)
where TEnum : struct
{
// Unfortunately this boxing/unboxing is the easiest way
// to do this due to C#'s lack of a where T : enum constraint
// (there are ways around this, but they involve some
// frustrating code).
int flagsValue = (int)(object)flags;
foreach (int flag in Enum.GetValues(typeof(TEnum)))
{
if ((flagsValue & flag) == flag)
{
// Once again: an unfortunate boxing/unboxing
// due to the lack of a where T : enum constraint.
yield return (TEnum)(object)flag;
}
}
}
}
所以你的cmdSearch_Click
处理程序看起来像这样:
private void cmdSearch_Click(object sender, EventArgs e)
{
if (qFlag == QueryFlags.None)
{
rtfLog.AppendText("\nNo search criteria selected.");
return;
}
foreach (QueryFlag flag in qFlag.GetFlags())
{
rtfLog.AppendText(string.Format("\nSearching {0}", flag.ToString()));
// add switch for flag value
}
}
答案 1 :(得分:0)
简短,俗气,低效的方式:
qflag.ToString().Split('|')