#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;
}