11

我在通用 DataGrids 中显示业务对象,我想通过自定义属性设置列标题,例如:

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

问题:如何简单地在不同的属性上设置 Header 属性?

无法按照您建议的方式在继承的成员上设置属性,因为属性特定于类型。SetCustomAttribute 对您没有帮助 - 只有在运行时构造新类型时才有用。一旦一个属性被编译进去,你就不能在运行时改变它,因为它是元数据的一部分。

如果你想保持分离,你将不得不寻找另一种方式。

(您可以将属性设为虚拟,在 Presentation 类中覆盖它们并在覆盖上添加属性,但这看起来很狡猾,并没有真正分离任何东西 - 无论如何,您最终会在 TestPresentationBO 中得到一个完整的 TestBO 类......)

于 2010-03-01T11:09:29.090 回答
6

TestBovirtual 中创建属性并在TestPresentationBO. 这样你就可以添加属性了。

于 2010-03-01T11:05:06.313 回答
2

您可以像 WCF RIA 服务一样进行操作。向 TestBO 添加一个属性,例如 [Presentation] 将类型作为参数。这种新类型将重新定义属性,但具有表示属性。在运行时,您必须获取新类型的标识并获取其属性的自定义属性。

或者忘记属性并有一个字典将 BO 与表示 BO 类映射。这个演示 BO 类和上面做的一样,即用自定义属性重新定义属性。

演示 BO 类永远不会被实例化,它只是简单地反映以获取演示信息。

于 2010-03-01T11:10:09.487 回答
2

只是想,你不能用部分类和MetadatatypeAttribute解决这个问题吗?MVC2 使用此模式进行模型验证。

于 2010-03-01T11:14:24.647 回答
2

您是否使用 MVVM(模型视图视图模型)模式?在我看来,部分来自其他答案,你不能真正用你想要的自定义属性来做到这一点。但是,在我看来,你TestPresentationBO真的就像一个“视图模型” TestBO。视图模型基本上是业务或逻辑类的一种包装器或代理——这基本上是您想要的。(这个视图模型的总结可能不是 100% 准确的;我自己刚开始使用 MVVM。)

您可以创建一个TestBOViewModelto wrap TestBO,然后将集合传递TestBOViewModel给数据网格。当然,您可以用[Header("Object's name")]etc 装饰暴露包装类的属性。这不使用继承,但我不明白为什么在这种情况下需要使用继承。但是,使用视图模型确实可以通过使用包装器(视图模型)将您的演示文稿(视图)与数据(模型)完全分开。

有关 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 回答
1

对于 C# 6.0,您可以轻松隐藏继承的成员并引入您自己的属性。但是,这可能会隐藏原始属性上的任何属性。此外,这种简化的语法使属性只读,因此您可能需要自己管道获取/设置。

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 回答