Какой подход я должен использовать при создании пользовательского элемента управления WPF? - PullRequest
3 голосов
/ 25 апреля 2011

Я собираюсь переделать старое приложение WinForms как приложение WPF. Ядром этого приложения является пользовательский «сеточный» компонент. Я хотел бы поделиться некоторыми идеями о том, как сделать это в качестве компонента WPF.

Приложение отображает сетку данных для разных стран / секторов. Каждая ячейка сетки отображает различную информацию (например, график, изображение) в зависимости от доступных данных для этой страны / сектора.

У меня есть сборка модели домена, которую я хочу содержать в чистоте - чтобы максимально использовать ее повторно. Структура выглядит следующим образом:

  • Таблица
    • Континенты
    • Страны
    • Секторы
    • Данные [страна, сектор]

Сетка отображает страны внизу слева и сектора сверху.

В текущем приложении компонент сетки имеет свойство таблицы (POCO) и методы Refresh () для его перерисовки вручную. Таким образом, если таблица обновляется, родительский компонент компонента сетки обновляет ее. Компонент сетки также имеет ряд событий, которые запускаются при нажатии на континент, страну или ячейку, так что родитель может ответить с помощью всплывающих меню и т. Д.

Это все отлично работает.

Однако мне интересно, подходит ли эта модель для приложения WPF. Рассматривая многие из примеров WPF, они поддерживают привязку данных и т. Д. Но из простых примеров неясно, как я мог бы связать сложный объект с моими компонентами - или это даже стоило бы.

Кроме того, компонент WinForms нарисован полностью по собственному усмотрению - не используются субэлементы управления (например, метки). Было бы лучше использовать пользовательский элемент управления WPF и создать таблицу из GridLayout и множества элементов управления Label, Shape и т. Д.? На практике это может быть 20 строк и 20 столбцов в сетке, и пользователь регулярно удаляет и добавляет страны / сектора (строки / столбцы) при использовании приложения.

Моя ближайшая цель - убедиться, что мой дизайн хорошо работает в экосистеме WPF, но у меня есть вторичная цель - научиться работать с WPFy - учитывая, что это мое первое приложение WPF. Я в восторге от использования создания общего приложения WPF - это просто пользовательский элемент управления, который остается немного размытым (даже после небольшого прочтения).

Любые идеи / рекомендации будут оценены.

1 Ответ

1 голос
/ 26 апреля 2011

Вы определенно хотите адаптировать подход MVVM, как указано Джошем Смитом .На практике это означает, что ваш пользовательский компонент сетки будет содержаться в его собственном представлении.Поддержка представления будет вашей ViewModel, где вы определите ObservableCollection объектов, содержащих ваши данные.Эти объекты, вероятно, будут получены из вашей модели.Это взаимодействие показано ниже:

Модели:

public class TableData
{
    public string Country { get; set; }
    public string Continent { get; set; }
    public object Sector { get; set; }
}

public class TableManager : ITableManager
{
    public Collection<TableData> Rows;

    public void GetData()
    {
        this.Rows = new Collection<TableData>();
        this.Rows.Add(...
    }
}

ViewModel:

public class TableViewModel
{
    private ITableManager _tableManager;

    public TableViewModel() : base(new TableManager())
    {
    }

    // for dependency injection (recommended)
    public TableViewModel(ITableManager tableManager)
    {
        _tableManager = tableManager;
        _tableManager.GetData();
    }

    public ObservableCollection<TableData> Rows
    { 
        get { return _tableManager.Rows; }
    }
}

Просмотр:

<ctrls:CustomDataGrid
    ItemsSource={Binding Rows}
    AutoGenerateColumns=True
    >
    <!-- Use AutoGenerateColumns if the # of sectors is dynamic -->
    <!-- Otherwise, define columns manually, like so: -->
    <DataGridTextColumn
         Width="*"
         Header="SectorA"
         Binding="{Binding Country}
         />
</ctrls:CustomDataGrid>

Я использовал CustomDataGrid в представлении, потому что я предполагаю, что вы собираетесь создать подкласс для своей собственной DataGrid.Это позволит вам переопределить события, чтобы настроить DataGrid по своему вкусу:

public class CustomDataGrid : DataGrid
{
    public override Event... 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...