11

一般的な DataGrid でビジネス オブジェクトを表示していますが、次のようなカスタム属性を使用して列ヘッダーを設定したいと考えています。

class TestBo
 {
    [Header("NoDisp")]
    public int ID {get; set;}

    [Header("Object's name")]
    public String Name { get; set; }
}

ここまでは順調ですが、継承によってディスプレイをデータから分離したいと思います。

class TestBO
{
   public int ID {get; set;}
   public String Name { get; set; }
}

class TestPresentationBO : TestBO
{
  //Question: how to simply set the Header attribute on the different properties?
}

Child コンストラクターで SetCustomAttribute を使用したリフレクションによる解決策が見えますが、面倒なので、この問題に対するシンプルでエレガントなトリックはありますか?

データとプレゼンテーションの分離を壊さないようにしてください ;o)

4

6 に答える 6

8

質問: さまざまなプロパティでヘッダー属性を簡単に設定する方法を教えてください。

属性は型に固有であるため、提案した方法で継承されたメンバーに属性を設定する方法はありません。SetCustomAttribute は役に立ちません。実行時に新しい型を構築する場合にのみ有効です。属性がコンパイルされると、それはメタデータの一部であるため、実行時に変更することはできません。

分離を維持したい場合は、別の方法を見つける必要があります。

(プロパティを仮想化し、Presentation クラスでそれらをオーバーライドし、オーバーライドに属性を追加することもできますが、これは危険に見え、実際には何も分離しません - とにかく TestPresentationBO で完全な TestBO クラスになります...)

于 2010-03-01T11:09:29.090 に答える
6

virtual でプロパティを作成しTestBo、 でオーバーライドしますTestPresentationBO。そうすれば、属性を追加できます。

于 2010-03-01T11:05:06.313 に答える
2

MVVM (モデル ビュー ビュー モデル) パターンを使用していますか? 私には、他の回答の一部から、あなたが望むようにカスタム属性でこれを実際に行うことはできないようです。しかし、あなたのTestPresentationBOは本当に「ビューモデル」のようなものだと私には思えますTestBO。ビュー モデルは基本的に、ビジネス クラスまたはロジック クラスの一種のラッパーまたはサロゲートです。これは基本的に必要なものです。(このビュー モデルの概要は 100% 正確ではない可能性があります。私は MVVM を使い始めたばかりです。)

TestBOViewModelラップする を作成してからTestBO、コレクションをデータグリッドに渡すことができますTestBOViewModel。もちろん、ラップされたクラスを公開するプロパティを装飾することもできます[Header("Object's name")]。これは継承を使用しませんが、この状況で継承を使用する必要がある理由がわかりません。ただし、ビュー モデルを使用すると、ラッパー (ビュー モデル) を使用してプレゼンテーション (ビュー) をデータ (モデル) から明確に分離できます。

MVVM パターンの詳細については、WPF Apps With The Model-View-ViewModel Design Patternが興味深い読み物であることがわかりました。

このようなもの。もちろん、ここにも検証やその他の機能を追加できます。

public class TestBOViewModel // extend from DependencyObject 
{                            // if you want to use dependency properties

    private TestBO _myBO;

    public TestBOViewModel(TestBO bo)
    {
        _myBO = bo;
    }

    [Header("NoDisp")]
    public int ID 
    {
        get { return _myBO.ID; }
        set { _myBO.ID = value; }
    }
}
于 2010-03-01T11:29:35.850 に答える
2

考えてみれば、これを部分クラスとMetadatatypeAttributeで解決できないのでしょうか? MVC2 は、モデルの検証にこのパターンを使用します。

于 2010-03-01T11:14:24.647 に答える
2

WCF RIA サービスのように実行できます。[Presentation] のように、タイプをパラメーターとして受け取る属性を TestBO に追加します。この新しいタイプは、プロパティを再定義しますが、プレゼンテーション属性を使用します。実行時に、新しい型の ID を取得し、そのプロパティのカスタム属性を取得する必要があります。

または、属性を忘れて、BO をプレゼンテーション BO クラスにマッピングする辞書を作成します。このプレゼンテーション BO クラスは、上記と同じことを行います。つまり、カスタム属性でプロパティを再定義します。

プレゼンテーション BO クラスはインスタンス化されることはなく、プレゼンテーション情報を取得するために反映されるだけです。

于 2010-03-01T11:10:09.487 に答える
1

C# 6.0 では、継承されたメンバーを簡単に非表示にして、独自の属性を導入できます。ただし、これにより、元のプロパティの属性が非表示になる場合があります。また、この単純化された構文ではプロパティが読み取り専用になるため、get/set を自分でパイプする必要がある場合があります。

public class User
{
    public string Login { get; set; }
}


public class UserDetail : User
{
    [Display(Name = "Login:")]
    public new string Login => base.Login;
}
于 2016-11-24T12:14:11.707 に答える