Lier une liste dans un FlowDocument à une liste?
j'ai un FlowDocument contenant des trucs lié à mon ViewModel comme ceci:
<FlowDocumentReader>
<FlowDocument>
<Paragraph>
<Run Text="{Binding MyTextProperty}"/>
</Paragraph>
</FlowDocument>
</FlowDocumentReader>
maintenant je veux afficher une liste de classe en utilisant une sorte de Dataemplate, mais je n'ai aucune idée de comment commencer. Dire que j'ai une classe de la forme:
public MyClass
{
String Title {get;set;}
String FlowText {get;set;}
}
public List<MyClass> MyList {get;set;}
Et j'aimerais lier cela à la FlowDocument Liste, comme ceci:
<FlowDocumentReader>
<FlowDocument>
<List Items="{Binding MyList}">
<Bold><Run Text="{Binding Title}"/></Bold>
<LineBreak/>
<Run Text="{Binding FlowText}"/>
</Paragraph>
</FlowDocument>
</FlowDocumentReader>
bien sûr, cela ne fonctionne pas - mais je n'ai trouvé aucune explication sur la façon de lier les Listes FlowDocument à l'aide de Modèles - est-ce possible?
1 réponses
Voir cette question.
je pense que vous avez deux options
- utilisation D'un ItemsControl
- en utilisant une propriété attachée
mise à Jour
Une solution plus dynamique utilisant deux propriétés attachées. Une ressource avec le modèle est ajoutée au paragraphe (qui doit avoir le x:Shared="False"
attribut, sinon, nous allons continuer à ajouter des éléments identiques sur et plus). Puis la liste des sources et le nom de la ressource template est défini comme propriétés jointes.
dans le callback PropertyChanged, une vérification est faite que les deux propriétés sont définies et puis un Span
élément est créé pour chaque élément dans la Liste. Les éléments span DataContext
est défini à l'élément courant pour faire fonctionner les fixations
<FlowDocumentReader xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib">
<FlowDocument>
<Paragraph behaviors:ParagraphInlineBehavior.ParagraphInlineSource="{Binding MyList}"
behaviors:ParagraphInlineBehavior.TemplateResourceName="inlineTemplate">
<Paragraph.Resources>
<Collections:ArrayList x:Shared="False" x:Key="inlineTemplate">
<Bold>
<Run Text="{Binding Title}"/>
</Bold>
<LineBreak/>
<Run Text="{Binding FlowText}"/>
<LineBreak/>
</Collections:ArrayList>
</Paragraph.Resources>
</Paragraph>
</FlowDocument>
</FlowDocumentReader>
Paragrapheinlinebehavior
public class ParagraphInlineBehavior : DependencyObject
{
public static readonly DependencyProperty TemplateResourceNameProperty =
DependencyProperty.RegisterAttached("TemplateResourceName",
typeof(string),
typeof(ParagraphInlineBehavior),
new UIPropertyMetadata(null, OnParagraphInlineChanged));
public static string GetTemplateResourceName(DependencyObject obj)
{
return (string)obj.GetValue(TemplateResourceNameProperty);
}
public static void SetTemplateResourceName(DependencyObject obj, string value)
{
obj.SetValue(TemplateResourceNameProperty, value);
}
public static readonly DependencyProperty ParagraphInlineSourceProperty =
DependencyProperty.RegisterAttached("ParagraphInlineSource",
typeof(IEnumerable),
typeof(ParagraphInlineBehavior),
new UIPropertyMetadata(null, OnParagraphInlineChanged));
public static IEnumerable GetParagraphInlineSource(DependencyObject obj)
{
return (IEnumerable)obj.GetValue(ParagraphInlineSourceProperty);
}
public static void SetParagraphInlineSource(DependencyObject obj, IEnumerable value)
{
obj.SetValue(ParagraphInlineSourceProperty, value);
}
private static void OnParagraphInlineChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Paragraph paragraph = d as Paragraph;
IEnumerable inlines = ParagraphInlineBehavior.GetParagraphInlineSource(paragraph);
string templateName = ParagraphInlineBehavior.GetTemplateResourceName(paragraph);
if (inlines != null && templateName != null)
{
paragraph.Inlines.Clear();
foreach (var inline in inlines)
{
ArrayList templateList = paragraph.FindResource(templateName) as ArrayList;
Span span = new Span();
span.DataContext = inline;
foreach (var templateInline in templateList)
{
span.Inlines.Add(templateInline as Inline);
}
paragraph.Inlines.Add(span);
}
}
}
}