1

OrderOrderName 、 OrderNum などのプロパティを持つクラスがあるとしましょう...

次に、ComboBoxこのクラスのアイテムのリストを入力するには、次のようにします。

comboBox1.DisplayMember = "OrderName";
comboBox1.ValueMember = "OrderNum";
comboBox1.DataSource = list.ToArray<Order>();

そのため、ここでは、「OrderName」などのコードでこれらのフィールドの名前をハードコーディングしています。フィールドの名前をハードコーディングするよりも、これを行うためのより良い方法はありますか? ある種の依存性注入のトリックが必要ですか? 何を指示してるんですか?

4

4 に答える 4

3

可能であれば、@JesseCSlicer が述べたように進めることができますが、ビジネス クラスを変更できない場合は、次のアプローチを取ることができます。

このSO answerに基づいて、独自のヘルパーを作成できます。

public static class PropHelper<T>
{
    public static string PropName<R>(Expression<Func<T,R>> exp)
    {
        var mem = exp.Body as MemberExpression;
        if(mem != null) return mem.Member.Name;     
        throw new ArgumentException("Invlaid Property Name");
    }
}

そしてそれを使用します:

comboBox1.DisplayMember = PropHelper<Order>.PropName(o => o.OrderName);
comboBox1.ValueMember = PropHelper<Order>.PropName(o => o.OrderNum);
comboBox1.DataSource = list.ToArray<Order>();
于 2012-09-25T17:21:37.423 に答える
2

これらは単なるプロパティOrderですよね?したがって、使用することができますconst-そしてそれはコード内のリテラルよりもはるかに優れています-しかし、必要に応じて実行時に確実に変更することができます。あなたは彼らが何であるかを知る必要があります。

クラスでは、「OrderName」と「OrderNum」はプロパティの名前を表す単なる文字列であるため、Orderクラスに他のプロパティがある場合は、それらのプロパティの名前を取得して、たとえば一部のユーザーから割り当てることができます。アクション。

必要に応じて、リフレクションを使用してOrderクラスを調べることができます。何かのようなもの:

Type theType =(typeof(Order));
// Get the public properties.
PropertyInfo[] thePropertyInfo =
    theType.GetProperties(BindingFlags.Public|BindingFlags.Instance);

そのPropertyInfo配列内の特定のプロパティの名前を取得するには、次のようにします。

thePropertyInfo[i].Name;

オブジェクトのi番目のプロパティの名前が表示されます。

したがって、たとえば、これらのプロパティをいくつかのリストに入れることができます。つまり、それ自体がコントロールにバインドされます。たとえば、ComboBox実行時に何DisplayMemberValueMember使用するかを選択し、それらを設定するだけで、バインドが自動的に更新されます。

于 2012-09-25T16:57:33.373 に答える
2

以下は、いくつかの ASP.NET アプリケーションで使用する、変更したクラスです。サンプルで割り当てる方法は次のとおりです。

var orders = model.GetOrders(...);

comboBox1.DisplayMember = OrderQueryResults.DisplayMember;
comboBox1.ValueMember = OrderQueryResults.ValueMember;
comboBox1.DataSource = orders.Results;

クラス:

public sealed class OrderQueryResults : IOrderQueryResults
{
    private const string DisplayName = "OrderName";

    private const string ValueName = "OrderNum";

    private readonly IEnumerable<IOrderQueryResult> results;

    private readonly object extra;

    private OrderQueryResults(IEnumerable<IOrderQueryResult> results, object extra)
    {
        this.results = results;
        this.extra = extra;
    }

    public string DisplayMember
    {
        get
        {
            return DisplayName;
        }
    }

    public string ValueMember
    {
        get
        {
            return ValueName;
        }
    }

    public IEnumerable<IOrderQueryResult> Results
    {
        get
        {
            return this.results;
        }
    }

    public object Extra
    {
        get
        {
            return this.extra;
        }
    }

    public static IOrderQueryResults Create(IEnumerable<IOrderQueryResult> results, object extra)
    {
        if (results == null)
        {
            throw new ArgumentNullException("results");
        }

        return new OrderQueryResults(results.ToList(), extra);
    }
}
于 2012-09-25T16:55:56.317 に答える
0

Orderクラスに配置されたconst文字列を使用し、データソースをバインドするときにこれらの定数をどこでも使用することをお勧めします。

于 2012-09-25T16:47:48.120 に答える