ShowModalDialog窗体在打印预览时出现的问题
本帖最后由 hnzgs 于 2011-3-25 07:58 编辑'环境:VS2008+CAD2010‘启动打印窗体
<CommandMethod("ShowPrint")> Public Shared Sub ShowPrint()
Dim frm As New FrmPrint
Application.ShowModalDialog(frm)
End Sub
用命令行方式(窗体没有运行时)调用过程一切正常
'测试函数
<CommandMethod("cs")> Public Shared Sub CS()
MultiSheetPreview()'过程代码见二楼、三楼
End Sub
但在窗体里用按钮调用的时候会出预览界面鼠标点击无反应的情况,好像无法获得焦点
'预览按钮代码
Private Sub BtnYuLan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnYuLan.Click
Me.Visible = False
MultiSheetPreview()'过程代码见二楼、三楼
Me.Visible = True
End Sub
求助如何解决? 本帖最后由 hnzgs 于 2011-3-25 07:57 编辑
附Kean代码
Public Shared Sub MultiSheetPreview()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Dim layoutsToPlot As New ObjectIdCollection()
Dim tr As Transaction = db.TransactionManager.StartTransaction()
Using tr
' First we need to collect the layouts to
' plot/preview in tab order
Dim layoutDict As New SortedDictionary(Of Integer, ObjectId)()
Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
For Each btrId As ObjectId In bt
Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
If btr.IsLayout AndAlso btr.Name.ToUpper() <> BlockTableRecord.ModelSpace.ToUpper() Then
' The dictionary we're using will
' sort on the tab order of the layout
Dim lo As Layout = DirectCast(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout)
layoutDict.Add(lo.TabOrder, btrId)
End If
Next
' Let's now get the layout IDs and add them to a
' standard ObjectIdCollection
Dim vc As SortedDictionary(Of Integer, ObjectId).ValueCollection = layoutDict.Values
For Each id As ObjectId In vc
layoutsToPlot.Add(id)
Next
' Committing is cheaper than aborting
tr.Commit()
End Using
' PlotEngines do the previewing and plotting
If PlotFactory.ProcessPlotState = Autodesk.AutoCAD.PlottingServices.ProcessPlotState.NotPlotting Then
Dim layoutNum As Integer = 0
Dim isFinished As Boolean = False
Dim isReadyForPlot As Boolean = False
While Not isFinished
' Create the preview engine with the appropriate
' buttons enabled - this depends on which
' layout in the list is being previewed
Dim flags As PreviewEngineFlags = PreviewEngineFlags.Plot
If layoutNum > 0 Then
flags = flags Or PreviewEngineFlags.PreviousSheet
End If
If layoutNum < layoutsToPlot.Count - 1 Then
flags = flags Or PreviewEngineFlags.NextSheet
End If
Dim pre As PlotEngine = PlotFactory.CreatePreviewEngine(CInt(flags))
Using pre
Dim stat As PreviewEndPlotStatus = MultiplePlotOrPreview(pre, True, layoutsToPlot, layoutNum, "")
' We're not checking the list bounds for
' next/previous as the buttons are only shown
' when they can be used
If stat = PreviewEndPlotStatus. Then
layoutNum += 1
ElseIf stat = PreviewEndPlotStatus.Previous Then
layoutNum -= 1
ElseIf stat = PreviewEndPlotStatus.Normal OrElse stat = PreviewEndPlotStatus.Cancel Then
isFinished = True
ElseIf stat = PreviewEndPlotStatus.Plot Then
isFinished = True
isReadyForPlot = True
End If
End Using
End While
' If the plot button was used to exit the preview...
If isReadyForPlot Then
Dim ple As PlotEngine = PlotFactory.CreatePublishEngine()
Using ple
Dim stat As PreviewEndPlotStatus = MultiplePlotOrPreview(ple, False, layoutsToPlot, -1, "c:\multisheet-previewed-plot")
End Using
End If
Else
ed.WriteMessage(vbLf & "Another plot is in progress.")
End If
End Sub
Private Shared Function MultiplePlotOrPreview(ByVal pe As PlotEngine, ByVal isPreview As Boolean, ByVal layoutSet As ObjectIdCollection, ByVal layoutNumIfPreview As Integer, ByVal filename As String) As PreviewEndPlotStatus
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Dim ret As PreviewEndPlotStatus = PreviewEndPlotStatus.Cancel
Dim layoutsToPlot As ObjectIdCollection
If isPreview AndAlso layoutNumIfPreview >= 0 Then
' Preview is really pre-sheet, so we reduce the
' sheet collection to contain the one we want
layoutsToPlot = New ObjectIdCollection()
layoutsToPlot.Add(layoutSet(layoutNumIfPreview))
Else
' If we're plotting we need all the sheets,
' so copy the ObjectIds across
Dim ids As ObjectId() = New ObjectId(layoutSet.Count - 1) {}
layoutSet.CopyTo(ids, 0)
layoutsToPlot = New ObjectIdCollection(ids)
End If
Dim tr As Transaction = db.TransactionManager.StartTransaction()
Using tr
' Create a Progress Dialog to provide info
' and allow thej user to cancel
Dim ppd As New PlotProgressDialog(isPreview, layoutsToPlot.Count, True)
Using ppd
Dim numSheet As Integer = 1
For Each btrId As ObjectId In layoutsToPlot
Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
Dim lo As Layout = DirectCast(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout)
' We need a PlotSettings object
' based on the layout settings
' which we then customize
Dim ps As New PlotSettings(lo.ModelType)
ps.CopyFrom(lo)
' The PlotSettingsValidator helps
' create a valid PlotSettings object
Dim psv As PlotSettingsValidator = PlotSettingsValidator.Current
' We'll plot the extents, centered and
' scaled to fit
psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents)
psv.SetUseStandardScale(ps, True)
psv.SetStdScaleType(ps, StdScaleType.ScaleToFit)
psv.SetPlotCentered(ps, True)
' We'll use the standard DWFx PC3, as
' this supports multiple sheets
psv.SetPlotConfigurationName(ps, "DWFx ePlot (XPS Compatible).pc3", "ANSI_A_(8.50_x_11.00_Inches)")
' We need a PlotInfo object
' linked to the layout
Dim pi As New PlotInfo()
pi.Layout = btr.LayoutId
' Make the layout we're plotting current
LayoutManager.Current.CurrentLayout = lo.LayoutName
' We need to link the PlotInfo to the
' PlotSettings and then validate it
pi.OverrideSettings = ps
Dim piv As New PlotInfoValidator()
piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled
piv.Validate(pi)
' We set the sheet name per sheet
ppd.PlotMsgString(PlotMessageIndex.SheetName) = (doc.Name.Substring(doc.Name.LastIndexOf("\") + 1) & " - ") + lo.LayoutName
If numSheet = 1 Then
' All other messages get set once
ppd.PlotMsgString(PlotMessageIndex.DialogTitle) = "Custom Preview Progress"
ppd.PlotMsgString(PlotMessageIndex.CancelJobButtonMessage) = "Cancel Job"
ppd.PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage) = "Cancel Sheet"
ppd.PlotMsgString(PlotMessageIndex.SheetSetProgressCaption) = "Sheet Set Progress"
ppd.PlotMsgString(PlotMessageIndex.SheetProgressCaption) = "Sheet Progress"
ppd.LowerPlotProgressRange = 0
ppd.UpperPlotProgressRange = 100
ppd.PlotProgressPos = 0
' Let's start the plot/preview, at last
ppd.OnBeginPlot()
ppd.IsVisible = True
pe.BeginPlot(ppd, Nothing)
' We'll be plotting a single document
pe.BeginDocument(pi, doc.Name, Nothing, 1, Not isPreview, filename)
End If
' Which may contains multiple sheets
ppd.LowerSheetProgressRange = 0
ppd.UpperSheetProgressRange = 100
ppd.SheetProgressPos = 0
Dim ppi As New PlotPageInfo()
pe.BeginPage(ppi, pi, (numSheet = layoutsToPlot.Count), Nothing)
ppd.OnBeginSheet()
pe.BeginGenerateGraphics(Nothing)
ppd.SheetProgressPos = 50
pe.EndGenerateGraphics(Nothing)
' Finish the sheet
Dim pepi As New PreviewEndPlotInfo()
pe.EndPage(pepi)
ret = pepi.Status
ppd.SheetProgressPos = 100
ppd.OnEndSheet()
numSheet += 1
' Update the overall progress
ppd.PlotProgressPos += (100 / layoutsToPlot.Count)
Next
' Finish the document
pe.EndDocument(Nothing)
' And finish the plot
ppd.PlotProgressPos = 100
ppd.OnEndPlot()
pe.EndPlot(Nothing)
End Using
End Using
Return ret
End Function
ShowModalDialog窗体在打印预览时出现的问题 有答案了吗 搞定了,采用StartUserInteraction 就可以了
页:
[1]