интерфейс документа с вкладками в использовании WPF только встроенных средств?

Я удивлен, что никто не думал об использовании формы iter с двумя аргументами :

from itertools import islice

def chunk(it, size):
    it = iter(it)
    return iter(lambda: tuple(islice(it, size)), ())

Демо:

>>> list(chunk(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13)]

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

from itertools import islice, chain, repeat

def chunk_pad(it, size, padval=None):
    it = chain(iter(it), repeat(padval))
    return iter(lambda: tuple(islice(it, size)), (padval,) * size)

Демонстрация:

>>> list(chunk_pad(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]
>>> list(chunk_pad(range(14), 3, 'a'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 'a')]

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

_no_padding = object()

def chunk(it, size, padval=_no_padding):
    if padval == _no_padding:
        it = iter(it)
        sentinel = ()
    else:
        it = chain(iter(it), repeat(padval))
        sentinel = (padval,) * size
    return iter(lambda: tuple(islice(it, size)), sentinel)

Демонстрация:

>>> list(chunk(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13)]
>>> list(chunk(range(14), 3, None))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]
>>> list(chunk(range(14), 3, 'a'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 'a')]

Я считаю, что это самый короткий предложенный блок, который предлагает дополнительное заполнение.

Как заметил Томаш Гандор , два чанкера заполнения неожиданно остановятся, если они встретят длинную последовательность значений пэдов. Вот последний вариант, который разумным образом решает эту проблему:

_no_padding = object()
def chunk(it, size, padval=_no_padding):
    it = iter(it)
    chunker = iter(lambda: tuple(islice(it, size)), ())
    if padval == _no_padding:
        yield from chunker
    else:
        for ch in chunker:
            yield ch if len(ch) == size else ch + (padval,) * (size - len(ch))

Демонстрация:

>>> list(chunk([1, 2, (), (), 5], 2))
[(1, 2), ((), ()), (5,)]
>>> list(chunk([1, 2, None, None, 5], 2, None))
[(1, 2), (None, None), (5, None)]

5
задан Michael Niemand 22 June 2009 в 12:24
поделиться

2 ответа

Это не так уж и сложно. Это кажется трудным, потому что есть много разных способов сделать это.

Попробуйте следующее:

<TabControl x:Name="documentArea"/>

Обработчик кнопки AddForm:

private void AddFormClick(object sender, RoutedEventArgs e)
{
    object form = GetNewForm();

    documentArea.Items.Add(form);
}

Вот и все. Вы должны реализовать GetNewForm () одним из двух способов. Он должен вернуть пользовательский элемент управления, который отображает форму.

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

5
ответ дан 13 December 2019 в 05:41
поделиться

Возможно, статья Джоша Смита о MVVM может дать вам представление о том, как разработать такой пользовательский интерфейс. Создаваемый пример представляет собой своего рода интерфейс документа с вкладками, поэтому вы можете использовать его в качестве начального блока.

7
ответ дан 13 December 2019 в 05:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: