#include "pch.h" #include "RichTextColumns.h" using namespace $safeprojectname$::Common; using namespace Platform; using namespace Platform::Collections; using namespace Windows::Foundation; using namespace Windows::UI::Xaml; using namespace Windows::UI::Xaml::Controls; using namespace Windows::UI::Xaml::Interop; /// /// Initialisiert eine neue Instanz der -Klasse. /// RichTextColumns::RichTextColumns() { HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Left; } DependencyProperty^ ItemPage::_columnTemplateProperty = nullptr; DependencyProperty^ ItemPage::_richTextContentProperty = nullptr; void ItemPage::RegisterDependencyProperties() { if (_columnTemplateProperty == nullptr) { _columnTemplateProperty = DependencyProperty::Register("ColumnTemplate", TypeName(DataTemplate::typeid), TypeName(RichTextColumns::typeid), ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback( &RichTextColumns::ResetOverflowLayout))); } if (_richTextContentProperty == nullptr) { _richTextContentProperty = DependencyProperty::Register("RichTextContent", TypeName(RichTextBlock::typeid), TypeName(RichTextColumns::typeid), ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback( &RichTextColumns::ResetOverflowLayout))); } } /// /// Identifiziert die -Abhängigkeitseigenschaft. /// DependencyProperty^ RichTextColumns::ColumnTemplateProperty::get() { return _columnTemplateProperty; } /// /// Identifiziert die -Abhängigkeitseigenschaft. /// DependencyProperty^ RichTextColumns::RichTextContentProperty::get() { return _richTextContentProperty; } /// /// Wird aufgerufen, wenn der Inhalt oder die Überlaufvorlage geändert wird, um das Spaltenlayout neu zu erstellen. /// /// Instanz von , in der die Änderung /// erfolgt ist. /// Ereignisdaten, die die jeweilige Änderung beschreiben. void RichTextColumns::ResetOverflowLayout(DependencyObject^ d, DependencyPropertyChangedEventArgs^ e) { (void) e; // Nicht verwendeter Parameter auto target = dynamic_cast(d); if (target != nullptr) { // Bei tiefgreifenden Änderungen das Layout von Grund auf neu erstellen target->_overflowColumns = nullptr; target->Children->Clear(); target->InvalidateMeasure(); } } /// /// Bestimmt, ob zusätzliche Überlaufspalten erforderlich sind und ob vorhandene Spalten /// entfernt werden können. /// /// Die Größe des verfügbaren Platzes zum Beschränken der /// Anzahl zusätzlicher Spalten, die erstellt werden können. /// Die daraus resultierende Größe des ursprünglichen Inhalts zuzüglich der zusätzlichen Spalten. Size RichTextColumns::MeasureOverride(Size availableSize) { if (RichTextContent == nullptr) { Size emptySize(0, 0); return emptySize; } // Sicherstellen, dass RichTextBlock ein untergeordnetes Element ist. Das Fehlen // einer Liste zusätzlicher Spalten dient dabei als Indiz, dass dies noch // nicht geschehen ist if (_overflowColumns == nullptr) { Children->Append(RichTextContent); _overflowColumns = ref new Vector(); } // Mit dem Messen des ursprünglichen RichTextBlock-Inhalts beginnen RichTextContent->Measure(availableSize); auto maxWidth = RichTextContent->DesiredSize.Width; auto maxHeight = RichTextContent->DesiredSize.Height; auto hasOverflow = RichTextContent->HasOverflowContent; // Sicherstellen, dass genügend Überlaufspalten zur Verfügung stehen unsigned int overflowIndex = 0; while (hasOverflow && maxWidth < availableSize.Width && ColumnTemplate != nullptr) { // Vorhandene Überlaufspalten so lange verwenden, bis alle aufgebraucht sind, und // dann weitere aus der bereitgestellten Vorlage erstellen RichTextBlockOverflow^ overflow; if (_overflowColumns->Size > overflowIndex) { overflow = _overflowColumns->GetAt(overflowIndex); } else { overflow = safe_cast(ColumnTemplate->LoadContent()); _overflowColumns->Append(overflow); Children->Append(overflow); if (overflowIndex == 0) { RichTextContent->OverflowContentTarget = overflow; } else { _overflowColumns->GetAt(overflowIndex - 1)->OverflowContentTarget = overflow; } } // Die neue Spalte messen und bei Bedarf eine Wiederholung vorbereiten Size remainingSize(availableSize.Width - maxWidth, availableSize.Height); overflow->Measure(remainingSize); maxWidth += overflow->DesiredSize.Width; maxHeight = __max(maxHeight, overflow->DesiredSize.Height); hasOverflow = overflow->HasOverflowContent; overflowIndex++; } // Zusätzliche Spalten von der Überlaufkette trennen, diese aus unserer privaten Liste // von Spalten entfernen, und sie als untergeordnete Elemente entfernen if (_overflowColumns->Size > overflowIndex) { if (overflowIndex == 0) { RichTextContent->OverflowContentTarget = nullptr; } else { _overflowColumns->GetAt(overflowIndex - 1)->OverflowContentTarget = nullptr; } while (_overflowColumns->Size > overflowIndex) { _overflowColumns->RemoveAt(overflowIndex); Children->RemoveAt(overflowIndex + 1); } } // Abschließend ermittelte Größe melden Size resultingSize(maxWidth, maxHeight); return resultingSize; } /// /// Ordnet den ursprünglichen Inhalt und alle zusätzlichen Spalten an. /// /// Definiert die Größe des Bereichs, in dem die untergeordneten Elemente angeordnet /// werden müssen. /// Die Größe des Bereichs, den die untergeordneten Elemente tatsächlich benötigt haben. Size RichTextColumns::ArrangeOverride(Size finalSize) { float maxWidth = 0; float maxHeight = 0; auto childrenIterator = Children->First(); while (childrenIterator->HasCurrent) { auto child = childrenIterator->Current; Rect childRect(maxWidth, 0, child->DesiredSize.Width, finalSize.Height); child->Arrange(childRect); maxWidth += child->DesiredSize.Width; maxHeight = __max(maxHeight, child->DesiredSize.Height); childrenIterator->MoveNext(); } Size resultingSize(maxWidth, maxHeight); return resultingSize; }