2012-04-17 3 views
3

wpf/mvvm을 사용하여 POS 응용 프로그램을 개발 중입니다. 트랜잭션 수명주기의 많은 부분에서 백그라운드에서 영수증이 인쇄됩니다. 영수증을 백그라운드에서 생성하고 인쇄하는 데 다른 예제를 사용했습니다. 나는 백그라운드에서 UserControl을 인쇄하고 있으며 모든 것이 훌륭해 보인다.WPF MVVM 배경 인쇄 데이터 바인딩 문제

그런 다음 컨트롤에 대한 ViewModel을 만들어서 인쇄 할 트랜잭션을로드 할 수 있습니다. 나는 2 개의 기본 textboxes로 시작했다 - Text header "클라이언트 영수증", 그리고 top header "Printed On : MM/dd/yy hh : mm tt".

  • 제어의 새로운 인스턴스를 생성합니다 : 나는 인쇄 버튼을 누르면 디버거가 라이프 사이클을 보여주는 방법

    이다.

  • 가 인쇄 대화 상자 &이 이름이 인쇄 대기열을 검색하여 원하는 사전 인쇄 크기를
  • 로드를 얻을 수있는 컨트롤에 대한 측정을 실행하는 INPC 속성에 대한 텍스트를 설정 뷰 모델의 새로운 인스턴스를 작성
  • ImageArea 너비가 내 UC와 동일하게 설정되어 있으므로 영수증 용지 크기에 맞게 컨트롤의 크기를 조정합니다 (현재 선택한 프린터의 배율을 조정할 필요가 없습니다)
  • "새"글자를 기반으로 격자를 재 측정하고 정렬합니다. 크기 조정 된 이미지 크기
  • UserControl을
  • 프린터 영수증을 뱉어를 전송 - -
  • 가 PrintDialog.PrintVisual 호출
  • 그리고 더 바인딩 된 텍스트를 가져 오기에 내 디버거 단계는 {_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"); 

그리고 (인수)보기 생성자

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

그리고 뷰 모델 :

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 (제어, "내 응용 프로그램") 후; 영수증이 출력되고 get {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] 
+1

디버그 옵션에서 "내 코드 만"사용하도록 설정했기 때문에 호출 스택에는 아마 한 항목 만있을 수 있습니다. 그것을 끄면 WPF의 호출 시퀀스가 ​​표시됩니다. – GazTheDestroyer

+0

풀 콜 스택 – nurgent

+0

으로 업데이트되었습니다. 이제 앱을 마쳤습니다. 나는 그것을 똑같이했고, 내가 이것을 읽었을 때 나는 내 자신을 읽고 있었다. 뷰 모델에 하드 코딩 된 값을 넣으면 코드가 개념 증명으로 보입니다. 실제로 긴 영수증에 페이징기를 사용했습니다. 나는이 방법이 이상하다고 생각했다. 대부분의 경쟁 업체는이를 위해보고 엔진을 사용하고 사용자는 모든 것을 사용자 정의 할 수 있습니다. 하지만 우리는이 방법을 사용하여 캔트 ..하지만 당신이 한 것처럼 생성자에서 datacontext 설정할 때 문제가 나를 위해 해결 될 듯. – GorillaApe

답변

3

DispatcherPriority보다 나중에 인쇄 작업을 대기 시키려면 Dispatcher을 사용하십시오. DataBind. 이렇게하면 모든 데이터 바인딩이 인쇄 작업 전에 처리됩니다.

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

그 덕분에, 고마워. – nurgent

2

어떤 것이 초기 바인딩 업데이트를 트리거하는지 (콜 스택에서 알 수 있습니까?) 나는 또한 알아내는 것에 흥미가있을 것이다.

주위에보기 컨텍스트로 설정 한 이후에 ViewModel 에 값을 설정하는 것이 좋습니다. 어쩌면 PropertyChanged 알림은 바인딩을 강제로 업데이트합니다. 예 :

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

오직 추측. :/

+0

데이터 설정을 바꿨으며 주사위는 사용하지 않았습니다. 내가 스택에 편집을 메인에 게시했다. – nurgent

관련 문제