2010-12-03 4 views
1

Vous cherchez un moyen simple et élégant d'afficher un visuel donné à l'utilisateur. La seule façon de penser à ma tête est de le claquer dans un pinceau et de le peindre sur un rectangle qui se trouve dans un ScrollViewer. Pas exactement la meilleure option.Manière conviviale d'afficher un visuel dans une application WPF?

+0

Quel est le besoin d'un tel lien de bas niveau? –

+1

Cela ressemble à l'une de ces questions qui pourraient bénéficier d'une description de niveau supérieur de ce dont vous avez vraiment besoin afin que nous puissions vous donner des alternatives. – Tergiver

+0

@Aaron @Tergiver Aucune alternative n'est possible. Je combine des visuels pour créer XpsDocuments. Je les connais comme visuels, bien qu'ils puissent être quelque chose qui s'étend de Visual. – Will

Répondre

0

Mon (actuel) est de frapper dans un XpsDocument et affichez-le dans un DocumentViewer. Je pourrais, je suppose, le faire un peu moins complexe, mais j'ai déjà l'infrastructure pour le faire de cette façon. Ce n'est pas 100%, mais ça marche.

D'abord, un comportement pour que je puisse se lier à DocumentViewer.Document (son un friggen POCO, urgh):

public sealed class XpsDocumentBinding 
{ 
    #region Document 
    /// <summary> 
    /// The <see cref="DependencyProperty"/> for <see cref="Document"/>. 
    /// </summary> 
    public static readonly DependencyProperty DocumentProperty = 
     DependencyProperty.RegisterAttached(
      "Document", 
      typeof(XpsDocument), // 
      typeof(XpsDocumentBinding), 
      new UIPropertyMetadata(null, OnDocumentChanged)); 

    /// <summary> 
    /// Gets the value of the <see cref="DocumentProperty">Document attached property</see> on the given <paramref name="target"/>. 
    /// </summary> 
    /// <param name="target">The <see cref="DependencyObject">target</see> on which the property is set.</param> 
    public static XpsDocument GetDocument(DependencyObject target) 
    { 
     return (XpsDocument)target.GetValue(DocumentProperty); 
    } 

    /// <summary> 
    /// Sets the <paramref name="value"/> of the <see cref="DocumentProperty">Document attached property</see> on the given <paramref name="target"/>. 
    /// </summary> 
    /// <param name="dependencyObject">The <see cref="DependencyObject">target</see> on which the property is to be set.</param> 
    /// <param name="value">The value to set.</param> 
    public static void SetDocument(DependencyObject target, XpsDocument value) 
    { 
     target.SetValue(DocumentProperty, value); 
    } 

    /// <summary> 
    /// Called when Document changes. 
    /// </summary> 
    /// <param name="sender">The sender.</param> 
    /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
    private static void OnDocumentChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     var viewer = sender as DocumentViewer; 
     if (viewer == null) 
      throw new InvalidOperationException(
       "This behavior is only valid on DocumetViewers."); 
     var doc = e.NewValue as XpsDocument; 
     if (doc == null) 
      return; 
     viewer.Document = doc.GetFixedDocumentSequence(); 
    } 
    #endregion 
} 

Puis dans mon modèle j'expose mon visuel comme XpsDocument

var pack = PackageStore.GetPackage(_uri); 
if (pack != null) 
    return new XpsDocument(pack, CompressionOption.SuperFast, _uri.AbsoluteUri); 

MemoryStream ms = new MemoryStream(2048); 
Package p = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite); 
PackageStore.AddPackage(_uri, p); 
XpsDocument doc = new XpsDocument(p, CompressionOption.SuperFast, _uri.AbsoluteUri); 

var writer = XpsDocument.CreateXpsDocumentWriter(doc); 
var collator = writer.CreateVisualsCollator(); 
// write the visuals using our collator 
collator.BeginBatchWrite(); 
collator.Write(Visual); 
collator.EndBatchWrite(); 
p.Flush(); 
return doc; 

Il suffit d'ajouter un DocumentViewer, de lier le résultat de la méthode de conversion via le comportement, et voilà. Je suis sûr qu'il y a un raccourci ici quelque part ...

1

Je ne vois pas comment vous pourriez faire cela car un Visual n'a ni une position ni une taille. Peut-être s'en tenir à FrameworkElement et créer un style pour cela?

+0

Eh bien, la taille et la position peuvent être déterminées par ce que c'est. Ce qui est ce que je cherche. Ce que je peux y mettre. – Will

2

Vous pouvez créer une enveloppe qui hérite de FrameworkElement qui soit héberger votre Visual ou un emballage générique qui hébergera tout objet provenant de Visual.

Jetez un oeil à l'exemple Visual.AddVisual ou, si vous voulez accueillir plus d'une réponse visuelle, jetez un oeil à l'exemple (partiel) dans Using DrawingVisual Objects

+0

Eh bien, si j'ai un visuel et le mettre dans un autre visuel, je ne suis pas beaucoup plus loin dans la ligne. Je jouais avec le DrawingVisual et je mettais peut-être ça dans une Image, mais c'était comme si je descendais dans le trou du lapin ... Comment pourrais-je arriver à l'une de ces expériences utilisateur où un utilisateur pourrait zoomer et faire un panoramique le visuel? – Will

+0

Bien que le lien pointe vers Visual.AddVisual, si vous regardez l'exemple, vous devez héberger le 'Visual' dans un' FrameworkElement' - il n'est pas nécessaire de le placer dans un 'DrawingVisual'. Désolé pour la confusion. – Samuel

Questions connexes