2013-04-08 151 views
0

如何通过调用打印方法来打印视图或窗口,而不使用如本示例中所示的RelayCommand进行打印:Print WPF Visuals with MVVM pattern从视图模型打印WPF视觉

var printDlg = new PrintDialog(); 
printDlg.PrintVisual(View, "JOB PRINTING") 
+1

如果您使用MVVM,为什么要让ViewModel知道您的View? – Dutts 2013-04-08 10:12:54

+0

为什么你不想使用命令?那么你总是可以将视图绑定到视图模型中的属性。我会适当地使用一个附加的行为。使命令成为附加属性,在该元素上,将命令OneWayToSource绑定到视图模型,在那里触发它,并通过附加的行为在控件上处理它。 – dowhilefor 2013-04-08 10:38:19

+0

我想在特定事件发生后打印文档/窗口..因此打印没有用RelayCommand调用,并且事件/条件发生在代码中..不在view/xaml上 – 2013-04-08 10:46:30

回答

0

好吧,这是一个快速,肮脏但可重复使用的附加行为类。 免责声明:我只是在几分钟之内就砍掉了它,它有缺陷,应该很容易克服。

首先我们需要我们的服务类。

public class VisualPrinter 
{ 
    private static RoutedUICommand PrintVisualCommand = new RoutedUICommand("PrintVisualCommand", "PrintVisualCommand", typeof(VisualPrinter)); 

    #region ab PrintCommand 

    public static ICommand GetPrintCommand(DependencyObject aTarget) 
    { 
     return (ICommand)aTarget.GetValue(PrintCommandProperty); 
    } 

    public static void SetPrintCommand(DependencyObject aTarget, ICommand aValue) 
    { 
     aTarget.SetValue(PrintCommandProperty, aValue); 
    } 

    public static readonly DependencyProperty PrintCommandProperty = 
     DependencyProperty.RegisterAttached("PrintCommand", typeof(ICommand), typeof(VisualPrinter), new FrameworkPropertyMetadata(PrintVisualCommand)); 

    #endregion 

    #region ab EnablePrintCommand 

    public static bool GetEnablePrintCommand(DependencyObject aTarget) 
    { 
     return (bool)aTarget.GetValue(EnablePrintCommandProperty); 
    } 
    public static void SetEnablePrintCommand(DependencyObject aTarget, bool aValue) 
    { 
     aTarget.SetValue(EnablePrintCommandProperty, aValue); 
    } 

    public static readonly DependencyProperty EnablePrintCommandProperty = 
     DependencyProperty.RegisterAttached("EnablePrintCommand", typeof(bool), typeof(VisualPrinter), new FrameworkPropertyMetadata(false, OnEnablePrintCommandChanged)); 

    private static void OnEnablePrintCommandChanged(DependencyObject aDependencyObject, DependencyPropertyChangedEventArgs aArgs) 
    { 
     var newValue = (bool)aArgs.NewValue; 
     var element = aDependencyObject as UIElement; 
     if(newValue) 
     { 
      element.CommandBindings.Add(new CommandBinding(PrintVisualCommand, OnPrintVisual)); 
     } 
    } 

    private static void OnPrintVisual(object aSender, ExecutedRoutedEventArgs aE) 
    { 
     // the element is the one were you set the EnablePrintCommand 
     var element = aSender as Visual; 
     var printDlg = new PrintDialog(); 
     // do the printing 
    } 

    #endregion 
} 

这里我们定义两个附加属性。 PrintCommand用于将实际的打印命令注入视图模型,这必须使用OneWayToSource完成。 第二个是EnablePrintCommand,用于启用打印,设置应打印哪个元素并注册命令绑定。

我目前的版本有一个缺陷,即你不能在同一个元素上设置两个属性,但这很容易被克服。因此,要打印的按钮,它看起来像这样:

<Grid local:VisualPrinter.EnablePrintCommand="True"> 
    <Button Content="Test" local:VisualPrinter.PrintCommand="{Binding ViewModelPrint, Mode=OneWayToSource"> 
</Grid> 

虽然ViewModelPrint是类型的ICommand的视图中的模型,其可以被执行,并且然后将打印网格(因此的按钮)的性质。