用户友好的方式在WPF应用程序中显示Visual?

时间:2010-12-03 19:36:41

标签: wpf user-interface

寻找一种简单,优雅的方式向用户显示任何给定的Visual。我能想到的唯一方法就是用画笔拍它并将它画在ScrollViewer中的Rectangle上。不完全是最好的选择。

3 个答案:

答案 0 :(得分:2)

您可以创建一个继承自FrameworkElement的包装器,它将托管您的Visual或一个通用包装器,它将托管从Visual派生的任何对象。

查看Visual.AddVisual中的示例,或者,如果您想要托管多个视觉效果,请查看Using DrawingVisual Objects

中的(部分)示例

答案 1 :(得分:1)

我没有看到你如何做到这一点,因为Visual既没有位置也没有大小。也许坚持使用FrameworkElement并为它创建一个样式?

答案 2 :(得分: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,通过行为将转换方法的结果绑定到它,就在那里。我确定这里有一条捷径...