3

私はおそらくこれを正しく表現していません(その場合はお詫びします)が、整数をバイナリ形式で表し、ユーザーがビットごとに「切り替える」ことができる Winforms コントロールを知っている人はいますか?

このための大まかなアプローチをまとめました。CheckListBoxコントロールといくつかの列挙型リストを使用し、設計時に各ビットにチェックボックスを追加します。

これは機能しますが、きちんとした解決策ではありません。おそらくもっときちんとしたアプローチがあるのではないかと思いました。他のプロジェクトで作業を繰り返す必要があるかもしれないので、これを行うためにカスタム コントロールをノックアップすることを考えましたが、これを行う既存の方法を誰かが知っていれば、興味があります!

4

1 に答える 1

1

私はこのアプローチを試します:

ビットごとの列挙型を作成します。

[Flags]
public enum MyBits
{
    MyFirstBit = 1 << 0,
    MySecondBit = 1 << 1,
    MyThirdBit = 1 << 2,
};

任意の列挙型を入力として受け入れる CheckedListBox に基づくカスタム コントロールを作成します。この列挙型を使用して、コントロールをチェックボックスで埋めます。列挙ごとに 1 つのチェックボックス:

public partial class EnumEditor : CheckedListBox
{
    public EnumEditor()
    {
        InitializeComponent();
        ItemCheck += EnumEditor_ItemCheck;
    }

    private object _value;
    public object Value
    {
        get
        {
            return _value;
        }
        set
        {
            if (value == null)
                throw new ArgumentNullException("Value");
            if (!value.GetType().IsEnum)
                throw new ArgumentNullException("Value should be enumerable.");
            if (value.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length == 0)
                throw new ArgumentNullException("Value must be marked with [Flags].");
            _value = value;
            Rebuild();
        }
    }

    public event EventHandler<EnumValueChangeEventArgs> ValueChanged;

    protected virtual void OnValueChanged(object value)
    {
        EventHandler<EnumValueChangeEventArgs> valueChanged = ValueChanged;
        if (valueChanged != null)
            valueChanged(this, new EnumValueChangeEventArgs { Value = value });
    }

    private void Rebuild()
    {
        Items.Clear();
        if (_value != null)
        {
            foreach (object value in Enum.GetValues(_value.GetType()))
                Items.Add(value, ((int)_value & (int)value) != 0);
        }
    }

    void EnumEditor_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        ulong bits = Convert.ToUInt64(_value);
        ulong bit = Convert.ToUInt64(Items[e.Index]);
        if (e.NewValue == CheckState.Checked)
            bits = bits | bit;
        else
            bits = bits & ~bit;
        _value = Enum.ToObject(_value.GetType(), bits);
        OnValueChanged(_value);
    }
}

public class EnumValueChangeEventArgs : EventArgs
{
    public object Value
    {
        get;
        set;
    }
}
于 2013-04-28T13:13:38.727 に答える