11

データバインディングを使用してデータを収集するwinformアプリケーションがあります。文字列を使用してプロパティtexteditにリンクする必要があることを除いて、すべて問題ないように見えます。

Me.TextEdit4.DataBindings.Add(New System.Windows.Forms.Binding("EditValue", Me.MyClassBindingSource, "MyClassProperty", True))

これは問題なく動作しますが、クラスのプロパティ名を変更すると、コンパイラは明らかに警告しません。

リフレクションによってプロパティ名を取得できるようにしたいのですが、必要なプロパティの名前を指定する方法がわかりません (クラスのすべてのプロパティを反復処理する方法しか知りません)

何か案が?

4

6 に答える 6

8

C# 3.0 を使用している場合、プロパティの名前をハードコードせずに動的に取得する方法があります。

private string GetPropertyName<TValue>(Expression<Func<BindingSourceType, TValue>> propertySelector)
{
    var memberExpression = propertySelector.Body as MemberExpression;
    return memberExpression != null 
           ? memberExpression.Member.Name 
           : string.empty;
}

BindingSourceTypeデータソース オブジェクト インスタンスのクラス名はどこにありますか。

次に、ラムダ式を使用して、バインドするプロパティを厳密に型指定された方法で選択できます。

this.textBox.DataBindings.Add(GetPropertyName(o => o.MyClassProperty),
                              this.myDataSourceObject,
                              "Text");

これにより、すべてのデータバインディングを中断することなく、コードを安全にリファクタリングできます。ただし、式ツリーを使用することは、パフォーマンスに関してはリフレクションを使用することと同じです。

前のコードは非常に見苦しく、チェックもされていませんが、おわかりいただけたでしょうか。

于 2008-09-30T08:55:00.270 に答える
6

これが私が話していることの例です:

[AttributeUsage(AttributeTargets.Property)]
class TextProperyAttribute: Attribute
{}

class MyTextBox
{
    [TextPropery]
    public string Text { get; set;}
    public int Foo { get; set;}
    public double Bar { get; set;}
}


static string GetTextProperty(Type type)
{
    foreach (PropertyInfo info in type.GetProperties())
    {
        if (info.GetCustomAttributes(typeof(TextProperyAttribute), true).Length > 0)
        {
            return info.Name;
        }
    }

    return null;
}

...

Type type = typeof (MyTextBox);

string name = GetTextProperty(type);

Console.WriteLine(name); // Prints "Text"
于 2008-09-30T08:48:22.313 に答える
3

皮肉なことに、リフレクションは、その情報を取得するためにプロパティ名を提供することを期待しています:)

カスタム属性を作成し、それを目的のプロパティに適用できます。次に、この属性を持つプロパティの名前を簡単に取得できます。

于 2008-09-30T08:39:25.847 に答える
0

リフレクションを使用しても同じ問題が発生します。すべてのタイプのプロパティで適切なプロパティを見つけるには、その名前を知る必要があるからです。

于 2008-09-30T08:40:17.777 に答える
0

Type を反映することはできますが、そのメンバーを名前以外で反映することはできません。

それが唯一のプロパティである場合、または順序付けが確実にわかっている場合は、インデックスで見つけることができますが、一般的に言えば、文字列が最も安全な方法です。

名前を変更すると実行時例外が発生すると思いますが、100%確実ではありません。どちらの場合も、おそらくそれが最善の可能性です。

例外が自動的に発生しないと仮定すると、その名前のプロパティが存在するかどうかを確認する Debug.Assert を追加できますが、これも実行時のみです。

于 2008-09-30T08:40:35.360 に答える
0

1)必要な正確なプロパティ名を指定し、そのままにしておきます

2) そのプロパティ名を含むテストを書きます。

于 2008-09-30T08:42:25.587 に答える