2010-12-03 2 views
1

Ищет простой, элегантный способ отображения любого данного Visual для пользователя. Единственный способ, который я могу придумать, это пощекотать его кистью и нарисовать на прямоугольнике, который находится в ScrollViewer. Не совсем лучший вариант.Удобный способ отображения Visual в приложении WPF?

+0

В чем же потребность в такой низкоуровневой галстуке? – 2010-12-03 19:47:19

+1

Это похоже на один из тех вопросов, которые помогут получить более качественное описание того, что вам действительно нужно, чтобы мы могли предоставить вам альтернативы. – Tergiver 2010-12-03 21:10:01

+0

@Aaron @Tergiver Альтернативы не возможны. Я совмещаю визуальные эффекты для создания XpsDocuments. Я знаю их как Визуальные, хотя они могут быть чем-то, что простирается от Visual. – Will 2010-12-06 15:02:55

ответ

0

Мой (текущий) ответ должен хлопнуть его в XpsDocument и отобразить его в DocumentViewer. Я мог бы, я полагаю, сделать это немного менее сложным, но у меня уже есть инфраструктура, чтобы сделать это таким образом. Его не 100%, но он работает.

Во-первых, это поведение, так что я могу связать с DocumentViewer.Document (его 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 
} 

Тогда в моей модели я разоблачить мой визуальный как 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; 

Просто добавьте DocumentViewer, привяжите результат метода преобразования к нему через поведение, и вот оно. Я уверен, что здесь есть ярлык ...

1

Я не вижу способа, как вы могли это сделать, поскольку Visual не имеет ни позиции, ни размера. Возможно, придерживайтесь FrameworkElement и создавайте для него стиль?

2

Вы можете создать оболочку, наследующую от FrameworkElement, которая либо разместила бы ваш Visual, либо общую оболочку, на которой будет размещен любой объект, полученный из Visual.

Посмотрите на пример в Visual.AddVisual или, если вы хотите разместить более одного визуального, посмотрите на (частично), например, в Using DrawingVisual Objects

Смежные вопросы