Страницы

Поиск по вопросам

вторник, 12 февраля 2019 г.

ItemsControl: Доступ из элемента к сведениям о родителе

Имеется следующая разметка:




Здесь Items - некая коллекция элементов, упорядоченная по убыванию Weight. Что я хочу: подложить под TextBlock'и зеленый прямоугольник, но так, чтобы его ширина была пропорциональна значению Weight, причем за 100% принять большее значение (оно самое первое будет). Шаблон набросал, но что вписать в свойство Width никак не соображу. Тут надо, во-первых, учесть что эти 100% заведомо неизвестны, а во-вторых, что ширина Grid может быть любой.
Нарисовал что хочу получить:


Ответ

Если максимальный вес есть отдельно в VM, то получается такой вот код:




На Windows 7 выглядит так:

Если хотите, чтобы стиль был один и тот же, проще всего таки приспособить прямоугольник. Для этого концептуально проще всего использовать конвертер.
Например, так. Ширина прямоугольника равна доступной ширине грида, умноженной на отношение Weight к MaxWeight. Оформляем это в виде конвертера.
class ProportionConverter : IMultiValueConverter { public object Convert(object[] values, Type t, object p, CultureInfo ci) => (double)values[0] / (double)values[1] * (double)values[2];
public object[] ConvertBack(object value, Type[] tt, object p, CultureInfo ci) => throw new NotSupportedException(); }
И оформляем такую разметку:




Результат:


Для эстетов, которые не хотят плодить конвертеры, можно извратиться, и реализовать деление при помощи двух трансформаций, причём одну из них нужно обратить. Вот так:

Картинка получается та же.
Ещё один вариант, который предложил в комментариях @Pavel Mayorov

(Я пробовал ещё варианты с GradientBrush и RenderTransform через конвертер, они тоже работают.)

Комментариев нет:

Отправить комментарий