簡體   English   中英

WPF MVVM后台打印數據綁定問題

[英]WPF MVVM background printing databinding issue

我正在使用wpf / mvvm開發銷售點應用程序。 在交易生命周期的許多部分中,將在后台打印收據。 我已經使用其他示例在后台生成和打印收據。 我在后台打印UserControl,一切看起來都很棒。

然后我為控件創建了ViewModel,因此它可以加載要打印的事務。 我從2個基本文本框開始 - 文本標題“客戶收據”和頂部標題“打印在:MM / dd / yy hh:mm tt”。

這是調試器在按下打印按鈕時顯示生命周期的方式:

  • 創建新的控件實例。
  • 創建ViewModel的新實例
  • 設置INPC屬性的文本
  • 在Control上運行一個度量以獲得所需的預打印大小
  • 加載打印對話框並檢索名稱打印隊列
  • 縮放控件的大小以適合收據紙(不應該為我當前選擇的打印機縮放,因為ImageArea寬度設置與我的UC相同)
  • 根據“新”縮放圖像大小重新測量和排列網格
  • 調用PrintDialog.PrintVisual - 發送UserControl
  • 打印機吐出收據 - 沒有數據綁定文本
  • 然后,我的調試器進入get {return _HeaderText; 部分代碼 - 在控件已經打印之后。

有沒有辦法在控制器發送到打印機之前強制控制數據綁定,而無需在面板中加載控件並使其可見? 我希望能夠例如刷信用卡並讓它在背景中打印帶有簽名行的收據,從一個小的彈出窗口詢問CC詳細信息(或滑動)。

有沒有更好的方法來實現這一目標?

PrintReceipt方法:

ClientReceiptView control = new ClientReceiptView(Message);       
System.Windows.Controls.PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
PrintQueue ReceiptPrinter = new LocalPrintServer().GetPrintQueue("CITIZEN CT-S310");
PrintCapabilities PC = ReceiptPrinter.GetPrintCapabilities();
printDlg.PrintQueue = ReceiptPrinter;
control.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
Size PreGridSize = control.DesiredSize;
double Scale = Math.Min(PC.PageImageableArea.ExtentWidth / PreGridSize.Width, PC.PageImageableArea.ExtentHeight / PreGridSize.Height);
control.LayoutTransform = new System.Windows.Media.ScaleTransform(Scale, Scale);
Size PaperSize = new Size(PC.PageImageableArea.ExtentWidth, Math.Min(PC.PageImageableArea.ExtentHeight, PreGridSize.Height));
control.Measure(PaperSize);
Point ptGrid = new Point(PC.PageImageableArea.OriginWidth, PC.PageImageableArea.OriginHeight);
control.Arrange(new Rect(ptGrid, PaperSize));
printDlg.PrintVisual(control, "My App");

和View構造函數(帶參數)

public ClientReceiptView(string Header)
{
    InitializeComponent();
    vm = new ClientReceiptViewModel(Header);
    this.DataContext = vm;
}

而ViewModel:

public class ClientReceiptViewModel : ViewModelBase
{
    #region Properties

    private string _HeaderText;

    public string HeaderText
    {
        get { return _HeaderText; }
        set { _HeaderText = value; OnPropertyChanged("HeaderText"); }
    }

    private int _TripID;

    public int TripID
    {
        get { return _TripID; }
        set { _TripID = value; OnPropertyChanged("TripID"); }
    }

    private string _PrintedOn;

    public string PrintedOn
    {
        get { return _PrintedOn; }
        set { _PrintedOn = value; OnPropertyChanged("PrintedOn"); }
    }

    #endregion

    public ClientReceiptViewModel(string Header)
    {
        HeaderText = Header;
        TripID = 2220013;
        PrintedOn = "Printed: " + DateTime.Now.ToString("MM/dd/yy hh:mm tt");
    }
}

編輯:通過OnPropertyChanged(“HeaderText”)中斷來從綁定/創建調用堆棧:

Namespace.Main.POS.Receipts.ClientReceiptViewModel.PrintedOn.set(string value) Line 38  C#
Namespace.Main.POS.Receipts.ClientReceiptViewModel.SetData(string Header) Line 79 + 0x4f bytes  C#
Namespace.Main.POS.Receipts.ClientReceiptView.ClientReceiptView(string Header) Line 28 + 0x13 bytes C#
Namespace.Main.POS.Receipts.PrintReceipt.PrintClientReceipt(string Message) Line 12 + 0x1e bytes    C#
Namespace.Main.MainWindowView.button1_Click(object sender, System.Windows.RoutedEventArgs e) Line 23 + 0xb bytes    C#
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x78 bytes    
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xbe bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x79 bytes  
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs e) + 0x17 bytes 
PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnClick() + 0x4b bytes  
PresentationFramework.dll!System.Windows.Controls.Button.OnClick() + 0x4d bytes 
PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) + 0x9e bytes   
PresentationCore.dll!System.Windows.UIElement.OnMouseLeftButtonUpThunk(object sender, System.Windows.Input.MouseButtonEventArgs e) + 0x6c bytes 
PresentationCore.dll!System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) + 0x31 bytes    
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x29 bytes  
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x3e bytes    
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xbe bytes   
PresentationCore.dll!System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args, System.Windows.RoutedEvent newEvent) + 0x114 bytes    
PresentationCore.dll!System.Windows.UIElement.OnMouseUpThunk(object sender, System.Windows.Input.MouseButtonEventArgs e) + 0xc5 bytes   
PresentationCore.dll!System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) + 0x31 bytes    
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x29 bytes  
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x3e bytes    
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xbe bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x79 bytes  
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) + 0x41 bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) + 0x2c bytes    
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x1ff bytes   
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) + 0x45 bytes 
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) + 0x62 bytes  
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel) + 0x2c2 bytes 
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x67d bytes 
PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x75 bytes   
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0xbe bytes    
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) + 0x7d bytes    
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x53 bytes 
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x42 bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0xb4 bytes    
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) + 0x104 bytes    
[Native to Managed Transition]  
[Managed to Native Transition]  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) + 0xc1 bytes  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) + 0x49 bytes  
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) + 0x5b bytes  
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) + 0x74 bytes 
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) + 0x2b bytes 
PresentationFramework.dll!System.Windows.Application.Run() + 0x1b bytes 
Namespace.App.Main() + 0x5e bytes   C#
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.AppDomain.nExecuteAssembly(System.Reflection.RuntimeAssembly assembly, string[] args) + 0x9 bytes   
mscorlib.dll!System.Runtime.Hosting.ManifestRunner.Run(bool checkAptModel) + 0x6e bytes 
mscorlib.dll!System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() + 0x90 bytes 
mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext, string[] activationCustomData) + 0x65 bytes 
mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext) + 0xd bytes 
mscorlib.dll!System.Activator.CreateInstance(System.ActivationContext activationContext) + 0x44 bytes   
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() + 0x23 bytes   
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x63 bytes   
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0xb0 bytes    
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x2c bytes    
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   
[Native to Managed Transition]  

然后在printDlg.PrintVisual(控件,“我的應用程序”)之后; 發出后,收據打印出來然后斷點上的調用堆棧獲取{return _PrintedOn; }:

Namespace.Main.POS.Receipts.ClientReceiptViewModel.PrintedOn.get() Line 37  C#
[Native to Managed Transition]  
PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.GetValue(object item, int level) + 0x108 bytes    
PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.RawValue(int k) + 0x4a bytes  
PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.RawValue() + 0x12 bytes   
PresentationFramework.dll!MS.Internal.Data.ClrBindingWorker.RawValue() + 0x11 bytes 
PresentationFramework.dll!System.Windows.Data.BindingExpression.TransferValue(object newValue, bool isASubPropertyChange) + 0xa7 bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpression.Activate(object item) + 0x194 bytes 
PresentationFramework.dll!System.Windows.Data.BindingExpression.AttachToContext(System.Windows.Data.BindingExpression.AttachAttempt attempt) + 0x38d bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(bool lastChance) + 0x19 bytes    
PresentationFramework.dll!MS.Internal.Data.DataBindEngine.Task.Run(bool lastChance) + 0x31 bytes    
PresentationFramework.dll!MS.Internal.Data.DataBindEngine.Run(object arg) + 0xb6 bytes  
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x53 bytes 
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x42 bytes    
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() + 0x8d bytes  
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) + 0x38 bytes 
mscorlib.dll!System.Threading.ExecutionContext.runTryCode(object userData) + 0x51 bytes 
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6a bytes    
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0x7e bytes    
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x2c bytes    
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() + 0x68 bytes  
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() + 0x15e bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x63 bytes 
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0xbe bytes    
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) + 0x7d bytes    
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x53 bytes 
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x42 bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0xb4 bytes    
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) + 0x104 bytes    
[Native to Managed Transition]  
[Managed to Native Transition]  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) + 0xc1 bytes  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) + 0x49 bytes  
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) + 0x5b bytes  
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) + 0x74 bytes 
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) + 0x2b bytes 
PresentationFramework.dll!System.Windows.Application.Run() + 0x1b bytes 
Namespace.App.Main() + 0x5e bytes   C#
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.AppDomain.nExecuteAssembly(System.Reflection.RuntimeAssembly assembly, string[] args) + 0x9 bytes   
mscorlib.dll!System.Runtime.Hosting.ManifestRunner.Run(bool checkAptModel) + 0x6e bytes 
mscorlib.dll!System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() + 0x90 bytes 
mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext, string[] activationCustomData) + 0x65 bytes 
mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext) + 0xd bytes 
mscorlib.dll!System.Activator.CreateInstance(System.ActivationContext activationContext) + 0x44 bytes   
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() + 0x23 bytes   
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x63 bytes   
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0xb0 bytes    
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x2c bytes    
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   
[Native to Managed Transition]  

使用Dispatcher將打印作業DataBind稍后的DispatcherPriority而不是DataBind 這樣,所有數據綁定都會在打印作業之前得到處理。

Dispatcher.BeginInvoke(DispatcherPriority.Loaded,
    new Action(delegate() { printDlg.PrintVisual(control, "My App"); } ));

我不知道是什么觸發了初始綁定更新(你能從你的調用堆棧中得知嗎?)。 我也有興趣了解一下。

解決它的一種方法可能是在將ViewModel設置為視圖上下文設置它們。 也許PropertyChanged通知會強制綁定更新,例如:

public ClientReceiptView(string Header)
{
    InitializeComponent();
    vm = new ClientReceiptViewModel();
    this.DataContext = vm;
    vm.SetHeader(Header);
}

只是猜測。 :/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM