I have a Winforms application that has suddenly begun to incorrectly render RDLCs to both physical printers and Print To PDF. It is targeting .NET 4.5.2 and began to show this after an update to 4.7.2 last week. I am able to reproduce the issue on my testbed system as well.
Examples:
Correctly printed:
Incorrectly printed:
I am rendering the RDLC into a MemoryStream and passing that to a PrintDocument.
I've changed the DPI of the PrintDocument and tried different Fonts in the RDLC
Any help or a point in the right direction would be great.
EDIT:
Private Sub Export()
Dim RL As PageLayout = CType(_RenderLayout, PageLayout)
Dim deviceInfo As String = RL.GetDeviceInfo
Dim warnings() As Warning = Nothing
_streams = New List(Of Stream)()
_report.Render("Image", deviceInfo, AddressOf CreateStream, warnings)
Dim exportStream As Stream
For Each exportStream In _streams
exportStream.Position = 0
Next
End Sub
Private Function CreateStream(ByVal name As String, ByVal fileNameExtension As String, ByVal encoding As Encoding,
ByVal mimeType As String, ByVal willSeek As Boolean) As Stream
Dim stream As Stream = New MemoryStream
_streams.Add(stream)
_streamCount += 1
Return stream
End Function
Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
Dim pageImage As New Metafile(_streams(_currentPageIndex))
ev.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
ev.Graphics.DrawImage(pageImage, ev.PageBounds)
_currentPageIndex += 1
ev.HasMorePages = (_currentPageIndex < _streams.Count)
End Sub
Related
I've searched around but cannot find the solution. This Reading only x number of bytes from file in VB.NET seems to point me in the right direction but I can't get it to give me the HEX info I need...
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If (OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
TextBox1.Text = OpenFileDialog1.FileName
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim filename = TextBox1.Text
Dim arraySize = 5
Dim buffer() As Byte = New Byte(arraySize) {}
Using fs As New System.IO.FileStream(filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
fs.Read(buffer, 0, buffer.Length)
End Using
'this solves it!
Dim hextottext As String = System.Text.Encoding.UTF8.GetString(buffer)
MsgBox(hextottext)
End Sub
Thats the code I'm using - when stepping through it,
fs = System.IO.Filestream
and I have no idea why.
Basically I want to read the first 6 bytes, convert them to readable text from hex, this is for an .iso image file.
Thanks for the tip on the chr function, but I found this during my searches!
In my VB.net project, I am trying to call up multiple programs using an array to help clean up my code.
Currently, I have this code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles StartServer.Click
Dim proc As New ProcessStartInfo()
Dim prochide As New ProcessStartInfo()
prochide.WindowStyle = ProcessWindowStyle.Hidden
If CheckBox1.CheckState = 1 Then
proc.WorkingDirectory = TextBox1.Text
proc.FileName = "xserver.exe"
Process.Start(proc)
proc.FileName = "yserver.exe"
Process.Start(proc)
proc.FileName = "zserver.exe"
Process.Start(proc)
Else
prochide.WorkingDirectory = TextBox1.Text
prochide.FileName = "xserver.exe"
Process.Start(prochide)
prochide.FileName = "yserver.exe"
Process.Start(prochide)
prochide.FileName = "zserver.exe"
Process.Start(prochide)
End If
End Sub
What this does is allows me to hide the windows so they show up in task manager but the windows don't actually show up.
However, I would prefer to switch with this code or something similar to clean it up:
Dim servers(0 To 2) As String
servers(0) = "xserver.exe"
servers(1) = "yserver.exe"
servers(2) = "zserver.exe"
Then I can simplify the code:
Dim directory As String = TextBox1.Text
For Each fileName As String In servers
Next
However, I cannot figure out how to hide the windows in an array, since the .WindowStyle = ProcessWindowStyle.Hidden does not seem to work with array strings. Is there another way I can do this?Changing the method is fine, I just want to try to clean up the code since it seems a bit bulky right now.
Okay so I've finally checked this out, and this works for me:
Public Class Form1
Dim servers() As String = New String() {"cmd.exe|1", "cmd.exe|1", "cmd.exe|1"}
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim directory As String = TextBox1.Text
Dim prochide As New ProcessStartInfo()
prochide.WorkingDirectory = directory
For Each fileName As String In servers
Dim FileOptions() As String = Split(fileName, "|")
prochide.FileName = FileOptions(0)
prochide.WindowStyle = CType(FileOptions(1), ProcessWindowStyle)
Process.Start(prochide)
Next
End Sub
End Class
When using New String() you cannot declare the array with a limit. So that was our problem. :)
So instead of Dim servers(3)... or Dim servers(0 To 2)... you have to use Dim servers()...
I have a textbox(textbox1) which when the WPF Window is loaded, it used the UserProfile variable to show the current user directory in textbox1.text
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Dim defaultpath As String = Environment.CurrentDirectory
Environment.CurrentDirectory = Environment.GetEnvironmentVariable("UserProfile")
TextBox1.Text = defaultpath
End Sub
I also have a button that when clicked, uses FolderBrowserDialog to browse for folder then shows the new folder path in textbox1.text.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim fldDialog As New FolderBrowserDialog()
fldDialog.RootFolder = Environment.SpecialFolder.Desktop
fldDialog.ShowDialog()
Dim filepathstore As String = fldDialog.SelectedPath
TextBox1.Text = filepathstore
End Sub
The value now shows the path that was selected with FolderBrowserDialog.
How would I store this new value and when WPF Window is closed/reopen, displays this new value instead of the default value. (replace not delete default value)
This new value of the folderpath can change as many times as needed. However when a reset button is clicked, the WPF window goes back to default value.
It sounds like the easiest option is to save the value to a file that can be recalled at any time. The below code assume the value you want to save is in textbox1.text when the FormClosing event is called, and then loads it back into textbox1.text when the form is opened.
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Dim s As String
s = TextBox1.Text
Dim loc As String
loc = My.Computer.FileSystem.SpecialDirectories.MyDocuments & "/testfile.txt"
My.Computer.FileSystem.WriteAllText(loc, TextBox1.Text, False)
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim loc As String
loc = My.Computer.FileSystem.SpecialDirectories.MyDocuments & "/testfile.txt"
Dim s As String
s = My.Computer.FileSystem.ReadAllText(loc)
TextBox1.Text = s
End Sub
Let me know if you have a problem with this :)
I have to code a WPF application for college which reads from a csv file. I get a null reference exception when I want to output the parts of the CSV lines into arrays. You can find the line where the error happens in commentary. Here is the code.
Imports System.Windows.Forms
Imports System.IO
Imports System.Globalization
Class MainWindow
Private foldername As String
Private arrGemeenten As String()
Private arrOppervlakte As Double()
Private arrInwoners As Integer()
Private arrDeelgemeenten As Integer()
Private Sub cboProvincie_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboProvincie.SelectionChanged
CSVInlezen()
End Sub
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
FileBrowserAanmaken()
comboBoxVullen()
End Sub
Private Sub comboBoxVullen()
For Each file As String In IO.Directory.GetFiles(foldername)
If file.EndsWith(".csv") Then
Dim filenaam As String = System.IO.Path.GetFileNameWithoutExtension(file)
cboProvincie.Items.Add(filenaam)
End If
Next
End Sub
Private Sub FileBrowserAanmaken()
'folderbrowserdialog aanmaken
Dim fbd As New FolderBrowserDialog
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory
' Show the FolderBrowserDialog.
Dim result As DialogResult = fbd.ShowDialog()
If (result = Forms.DialogResult.OK) Then
foldername = fbd.SelectedPath
End If
End Sub
Private Sub CSVInlezen()
Dim filepath As String = foldername & "\" & cboProvincie.SelectedValue & ".csv"
If File.Exists(filepath) Then
fileInlezenHulpMethode(filepath)
End If
End Sub
Private Sub fileInlezenHulpMethode(ByVal path As String)
'declarations
Dim sr As New StreamReader(path)
Dim iTeller As Integer = 0
Dim arrLijn As String()
Dim culture As New System.Globalization.CultureInfo("nl-BE")
'eerste lijn meteen uitlezen, dit zijn kolomkoppen en hebben we niet nodig
'read out first line, these are titles and we don't need them
sr.ReadLine()
Do While sr.Peek <> -1
Dim lijn As String = sr.ReadLine()
arrLijn = lijn.Split(";")
arrGemeenten(iTeller) = Convert.ToString(arrLijn(0)) 'HERE I GET THE ERROR!
arrOppervlakte(iTeller) = Double.Parse(arrLijn(2), NumberStyles.AllowDecimalPoint, culture.NumberFormat)
arrInwoners(iTeller) = Integer.Parse(arrLijn(3), NumberStyles.Integer Or NumberStyles.AllowThousands, culture.NumberFormat)
arrDeelgemeenten(iTeller) = Convert.ToString(arrLijn(4))
Loop
End Sub
End Class
You haven't created the array, you have only created a reference for it. To create the array you need to specify a size, for example:
Private arrGemeenten As String(100)
However, to specify the size, you need to know the size when you create the array. (Well, actually you put all data in the first item, so just the size 1 would keep it from crashing, but I don't thing that's what you intended.) You probably want to use lists instead:
Private gemeenten As New List(Of String)()
Then you use the Add method to add items to the list:
gemeenten.Add(Convert.ToString(arrLijn(0)))
Also, consider putting the data in a single list of a custom object, instead of having several lists of loosely coupled data.
Good evening,
Following is the code I used for reading the files and folders from a drive etc.
Public Class LoadingBox
Public counter As ULong
Public OpenRecords As New Dictionary(Of String, MainWindow.records)
Public Path As String
Public Diskname As String
Private WithEvents BKWorker As New BackgroundWorker()
Public Sub New(ByVal _Path As String, ByVal _Diskname As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Path = _path
Diskname = _diskname
End Sub
Private Sub GetStructure(ByVal tempdir As String, ByVal ParentID As String, ByVal DiskName As String)
Dim maindir As DirectoryInfo = My.Computer.FileSystem.GetDirectoryInfo(tempdir)
For Each Dir As DirectoryInfo In maindir.GetDirectories
Try
Dim d As New MainWindow.records
d.Filename = Dir.Name
d.Folder = True
d.Rowid = Date.UtcNow.ToString() + counter.ToString()
d.Size = 0
d.ParentID = ParentID
d.DiskName = DiskName
d.DateCreated = Dir.CreationTimeUtc
d.DateModified = Dir.LastWriteTimeUtc
OpenRecords.Add(d.Rowid, d)
'Label1.Content = "Processing: " + Dir.FullName
BKWorker.ReportProgress(0, Dir.FullName)
counter = counter + 1
GetStructure(Dir.FullName, d.Rowid, DiskName)
Catch ex As Exception
End Try
Next
For Each fil As FileInfo In maindir.GetFiles
Try
Dim d As New MainWindow.records
d.Filename = fil.Name
d.Folder = False
d.Rowid = Date.UtcNow.ToString() + counter.ToString()
d.Size = fil.Length
d.ParentID = ParentID
d.DiskName = DiskName
d.DateCreated = fil.CreationTimeUtc
d.DateModified = fil.LastWriteTimeUtc
OpenRecords.Add(d.Rowid, d)
'Label1.Content = "Processing: " + fil.FullName
BKWorker.ReportProgress(0, fil.FullName)
counter = counter + 1
Catch ex As Exception
End Try
Next
End Sub
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
counter = 0
BKWorker.WorkerReportsProgress = True
AddHandler BKWorker.DoWork, AddressOf BKWorker_Do
AddHandler BKWorker.ProgressChanged, AddressOf BKWorker_Progress
AddHandler BKWorker.RunWorkerCompleted, AddressOf BKWorker_Completed
BKWorker.RunWorkerAsync()
'GetStructure(Path, "0", Diskname)
End Sub
Private Sub BKWorker_Do(ByVal sender As Object, ByVal e As DoWorkEventArgs)
'Throw New NotImplementedException
GetStructure(Path, "0", Diskname)
End Sub
Private Sub BKWorker_Progress(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
'Throw New NotImplementedException
Label1.Content = "Processing: " + e.UserState.ToString()
If ProgressBar1.Value = 100 Then
ProgressBar1.Value = 0
End If
ProgressBar1.Value = ProgressBar1.Value + 1
End Sub
Private Sub BKWorker_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
'Throw New NotImplementedException
MessageBox.Show("Completed")
Me.Close()
End Sub
End Class
However the problem is that, the background thread is able to read files very fast, but the UI thread is not able to keep up the speed with it, could you please advice me on how I can solve this issue.
You almost never want to report progress on every single item when you're iterating through that many items.
I would suggest finding some reasonable number of files to wait for before reporting progress. Every 5th or every 10th or so on. You probably want to take a look at what your normal number of files is. In other words, if you're normally processing only 25 files, you probably don't want to only update every 10 files. But if you're normally processing 25000 files, you could maybe even only update every 100 files.
One quick answer would be to only report the progress when a certain amount of time has passed that way if 10 files were processed in that time the UI isn't trying to update one each one. If things are processing that fast then you really don't need to update the user on every single file.
Also on a quick side note if your ProgressBar isn't actually reporting progress from 0 to 100% you might want to just set its IsIndeterminate property to true instead of increasing the percent and then resetting it back to 0.