4 Stimmen

Wie würde ich einen Absatz an einen TextBlock binden?

Wie würde ich eine Paragraph Objekt und binden sie an den TextBlock zur Verwendung in einem DataTemplate? Eine einfache Bindung bewirkt nichts, nur eine ToString() des Paragraph-Objekts.

Die InLines-Eigenschaft würde mich eine Liste von TextRuns hinzufügen lassen, die den Absatz manuell bilden, aber das kann nicht gebunden werden, und ich könnte wirklich mit einer Bindung basierte Lösung tun.

Geänderte Frage, um mich auf das zu konzentrieren, was ich wirklich tun muss.

0 Stimmen

Ich habe meine Antwort bearbeitet - ist Ihr Problem damit gelöst?

3voto

Robert Macnee Punkte 11480

Hier ist ein Beispiel mit einem verschachtelten ItemsControl. Leider wird ein TextBlock pro Inline erstellt, anstatt den ganzen Absatz in einen TextBlock zu packen:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:sys="clr-namespace:System;assembly=mscorlib"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid.Resources>
        <FlowDocument x:Key="document">
            <Paragraph><Run xml:space="preserve">This is the first paragraph.  </Run><Run>The quick brown fox jumps over the lazy dog.</Run></Paragraph>
            <Paragraph><Run xml:space="preserve">This is the second paragraph.  </Run><Run>Two driven jocks help fax my big quiz.</Run></Paragraph>
            <Paragraph><Run xml:space="preserve">This is the third paragraph.  </Run><Run>Sphinx of black quartz, judge my vow!</Run></Paragraph>
        </FlowDocument>
        <DataTemplate DataType="{x:Type Paragraph}">
            <ItemsControl ItemsSource="{Binding Inlines}" IsHitTestVisible="False">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </DataTemplate>
    </Grid.Resources>
    <ListBox ItemsSource="{Binding Blocks, Source={StaticResource document}}"/>
</Grid>

Wenn Sie einen Absatz pro Element wünschen, sollten Sie wahrscheinlich wie vorgeschlagen eine schreibgeschützte RichTextBox verwenden, oder tun, was diese Person getan hat, und von TextBlock ableiten so dass die Eigenschaft Inlines gebunden werden kann.

0 Stimmen

Ich ging mit der Ableitung von TextBlock-Methode, wie in diesem Forum-Post vorgeschlagen, wie das scheint, der am besten funktioniert. +1 zu Andy und joshperry für ähnliche Antworten, die von gearbeitet würde, wenn ich nicht mehrere Inlines benötigen:)

3voto

joshperry Punkte 39356

Ich hatte ein ähnliches Bedürfnis und löste es nach dem Vorbild von Andys Antwort... Ich habe einen BindableTextBlock erstellt:

class BindableTextBlock : TextBlock
{
    public Inline BoundInline
    {
        get { return (Inline)GetValue(BoundInlineProperty); }
        set { SetValue(BoundInlineProperty, value); }
    }

    public static readonly DependencyProperty BoundInlineProperty =
        DependencyProperty.Register("BoundInline", typeof(Inline), typeof(BindableTextBlock),
            new UIPropertyMetadata((PropertyChangedCallback)((d, e) => { ((BindableTextBlock)d).Inlines.Clear(); ((BindableTextBlock)d).Inlines.Add(e.NewValue as Inline); })));
}

Dann kann ich in meiner XAML an die BoundInline-Abhängigkeitseigenschaft binden:

    <DataTemplate x:Key="TempTemplate">
        <t:BindableTextBlock TextWrapping="Wrap" BoundInline="{Binding Path=TextInlines}" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" />
    </DataTemplate>

Der einzige Nachteil dabei ist, dass man nur eine einzige Root-Inline an den Textblock binden kann, was in meinem Fall gut funktioniert hat, da mein Inhalt in eine Top-Level-Span verpackt ist.

1voto

Andy Punkte 29060

Ich bin nicht sicher, ob man einen Absatz direkt an die Inlines eines TextBlocks binden kann. Allerdings konnte ich die Klasse BindableRun mit der Sie die Text-Eigenschaft von Run binden können. Würde das für Sie stattdessen funktionieren?

EDIT: Ich habe meine Antwort an die geänderte Frage angepasst.

0 Stimmen

Aber wie würde ich diesen Absatz anzeigen?

0voto

Christian Klauser Punkte 4316

Sie könnten versuchen, ein eigenes DataTemplate für Paragraph-Objekte zu erstellen, das jedes einzelne in ein eigenes FlowDocument verpackt, das dann über eine RichTextBox (natürlich schreibgeschützt) dargestellt wird

0 Stimmen

Alle diese Objekte verfügen über eine große Menge an eingebauten Funktionen, die sie ziemlich groß machen. Ich würde die Dinge gerne klein halten.

0 Stimmen

Bei einem VirtualizingStackPanel sind nur die wenigen sichtbaren Blöcke tatsächlich im Speicher vorhanden, wenn ich das Konzept der Virtualisierung von Panels richtig verstanden habe.

0voto

Jodrell Punkte 32818

Ich hatte fast das gleiche Problem und beantwortete es auf ähnliche Weise wie joshperry, sub-Classing TextBlock, um die Inlines Bindable zu machen. Darüber hinaus schrieb ich einen Konverter zwischen einem String von xaml Markup und einer InlineCollection.

Wie bindet man einen TextBlock an eine Ressource mit formatiertem Text?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X