C # добавить пользовательские атрибуты для родительского свойства в унаследованном классе - PullRequest
6 голосов
/ 01 марта 2010

Я отображаю бизнес-объект в общих 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?
}

Я вижу решение через отражение с помощью SetCustomAttribute в конструкторе Child, но оно будет громоздким, поэтому есть ли простой и элегантный прием для этой проблемы?

Пожалуйста, не дайте мне нарушить разделение данных / представлений; o)

Ответы [ 6 ]

6 голосов
/ 01 марта 2010

Вопрос: как просто установить атрибут Header для разных свойств?

Нет способа установить атрибут унаследованного члена так, как выпредложили, так как атрибуты являются специфическими для типа.SetCustomAttribute вам не поможет - это хорошо, когда вы создаете новые типы во время выполнения .После того, как атрибут был скомпилирован, вы не можете изменить его во время выполнения, поскольку он является частью метаданных.

Если вы хотите сохранить разделение, вам придется найти другой путь.

(Вымог бы сделать свойства виртуальными, переопределить их в классе Presentation и добавить атрибуты в переопределения, но это выглядит неуместно и на самом деле ничего не разделяет - в конечном итоге вы получите полный класс TestBO в вашем TestPresentationBO ...)

3 голосов
/ 01 марта 2010

Сделать свойства в TestBo виртуальными и переопределить их в TestPresentationBO. Таким образом, вы можете добавить атрибуты.

2 голосов
/ 01 марта 2010

Используете ли вы шаблон MVVM (модель-представление-модель)? Мне кажется, и частично из других ответов, что вы не можете сделать это с пользовательскими атрибутами, как вы хотите. Но мне также кажется, что ваш TestPresentationBO действительно похож на «модель просмотра» для TestBO. Модель представления - это своего рода обертка или суррогат для бизнес-класса или класса логики, а это то, что вам нужно. (Это краткое изложение модели представления может быть не на 100% точным; я только начинаю с MVVM.)

Вы можете создать TestBOViewModel для переноса TestBO, а затем передать коллекцию TestBOViewModel в сетку данных. Конечно, вы можете украсить свойства, обнажив обернутый класс, [Header("Object's name")] и т. Д. Это не использует наследование, но я не понимаю, почему вам нужно использовать наследование в этой ситуации. Тем не менее, при использовании модели представления чисто отделяется ваша презентация (представление) от ваших данных (модели) с помощью оболочки (модель представления).

Для получения дополнительной информации о шаблоне MVVM я нашел интересное прочтение: Приложения WPF с шаблоном проектирования Model-View-ViewModel .

Примерно так. Конечно, вы можете добавить здесь валидацию и другие полезности.

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; }
    }
}
2 голосов
/ 01 марта 2010

Просто подумайте, разве вы не можете решить эту проблему с помощью частичных классов и MetadatatypeAttribute ? MVC2 использует этот шаблон для проверки модели.

2 голосов
/ 01 марта 2010

Вы можете сделать это как WCF RIA Services. Добавьте атрибут в TestBO, например, [Presentation], принимая тип в качестве параметра. Этот новый тип будет переопределять свойства, но с атрибутами представления. Во время выполнения вы должны получить идентификатор нового типа и получить пользовательские атрибуты его свойств.

Или забудьте об атрибуте и получите словарь, отображающий BO с классом представления BO. Этот класс BO представления делает то же самое, что и выше, то есть переопределение свойств с помощью пользовательских атрибутов.

класс BO презентации никогда не создается, он просто отражается для получения информации о презентации.

0 голосов
/ 24 ноября 2016

Для 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;
}
...