عندك DataGridView ؟ تفضل معي وحولها إلى صورة Bmp !

27 08 2007

اثناء تصفحي للموقع الشهير http://www.codeproject.com/ وجدت مقاله رائعه يتحدث كاتبها حول كيفية حفظ اداة DataGridView ومحتوياتها ( من صفوف وأعمده ) على شكل صورة Bmp ، قد تروقك الفكره مثلما راقتني !

طيب الفكره كلها تدور في الـ Module التالية واستخدامها لفضاء الأسماء System.Drawing.Imaging وكذلك دالة API تدعى BitBlt ، انشيء Module جديده وضع فيها السطور التالية :

Imports System.Drawing.Imaging


Module DataGrid2Bitmap

    Private Declare Auto Function BitBlt Lib “gdi32.dll” _
    (ByVal pHdc As IntPtr, ByVal iX As Integer, _
    ByVal iY As Integer, ByVal iWidth As Integer, _
    ByVal iHeight As Integer, ByVal pHdcSource As IntPtr, _
    ByVal iXSource As Integer, ByVal iYSource As Integer, _
    ByVal dw As System.Int32) As Boolean

    Private Const SRC As Integer = &HCC0020


    Public Sub ConvertDG2BMP(ByVal dg As DataGridView, ByVal sFilePath As String)

        dg.Refresh()
        dg.Select()

        Dim g As Graphics = dg.CreateGraphics
        Dim ibitMap As New Bitmap(dg.ClientSize.Width, dg.ClientSize.Height, g)
        Dim iBitMap_gr As Graphics = Graphics.FromImage(ibitMap)
        Dim iBitMap_hdc As IntPtr = iBitMap_gr.GetHdc
        Dim me_hdc As IntPtr = g.GetHdc

        BitBlt(iBitMap_hdc, 0, 0, dg.ClientSize.Width, dg.ClientSize.Height, me_hdc, 0, 0, SRC)
        g.ReleaseHdc(me_hdc)
        iBitMap_gr.ReleaseHdc(iBitMap_hdc)

        If sFilePath = “” Then Exit Sub
        ibitMap.Save(sFilePath, ImageFormat.Bmp)

    End Sub

End Module

ثم في النافذه التي توجد عليها أداة الـ Datagridview وبعد عرض البيانات عليها ، نستدعي الـ Method المسماه ConvertDG2BMP ونرسل معها اسم الـ DataGridview :

        Try
            ‘Open a file dialog for saving map documents
            SaveFileDialog1.Title = “Save As BMP File”
            SaveFileDialog1.Filter = “Bitmap File (*.bmp)|*.bmp”

            If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
                Exit Sub
            End If

        Catch ex As Exception

            Exit Sub

        End Try

        ‘Exit if no map document is selected
        Dim sFilePath As String
        sFilePath = SaveFileDialog1.FileName
        If sFilePath = “” Then
            Exit Sub
        Else
            DataGrid2Bitmap.ConvertDG2BMP(DataGridView1, sFilePath)
        End If

ويفضل استخدام الأداة FileSaveDialog كما بالكود أعلاه .

تجربه ناجحه بإذن الله


الإجراءات

معلومات

8 ردود

15 06 2008
سيف

اخى النبهانى الرجاء شرح كيفية عدم تكرار البيانات فى عمود معين داخل الداتا قريد اثناء كتابة البيانات فى الخلايا

1 07 2008
alnabhani

اهلا بك اخي سيف ، وعذرا على التأخير في التعقيبب على تعقيبك حيث انني كنت مشغول فيما مضى ولم ارى تعقيبك الا الآن !

ساعطيك الفكرة وعليك التنفيذ ، اتفقنا ؟

الفكرة تكمن في ادخال البيانات الى row جديدة في الاداة ، وبعد الانتقال الى row آخر يتم التأكد من عدم تكرارها ، في حالة تكرارها يتم الغاؤها وحذفها ( حسب حاجتك )

هل وصلتك الفكرة ؟

3 09 2008
Black Fox

أخى العزيز النبهانى

أولا ابدأ حديثى بتوجيه تحيه طيبه و ابداء الشكر عن عملك جاهدا لمساعدة الاخوه المبرمجين من العرب

لكن اود ان الفت نظرك الى نقطه فى هذا المقال الا و هى انك تكبدت عناء استدعاء دوال API و التى أؤيد الاستاذ تركى العسيرى حفظه الله فى وصفه لها بأنها ” فقط للمبرمجين الشجعان ” و أضيف عليه انها مع بيئة الدوت نت للمبرمجين الانتحاريين لأسباب يطول شرحها

فى حين انك كان يمكنك تكبد هذا العناء بسهوله بالغه عن طريق استخدام الداله DrawToBitmap التابعه للأداه DataGridView و التى تؤدى الى اقتطاع جزء من الاداه او الاده كلها كصوره BMP

********
* مثال *
********
نبدأ باستيراد فضاء الاسماء NameSpace المسمى System.Drawing لاحتوائه على بعض الاصناف التى نحتاجها

Imports System.Drawing

و على فرض ان اداة الـDataGridView قد تمت تسميتها DGV و اننا وضعنا اداة صوره تدعى DGVShow

Dim B As Bitmap = New Bitmap(DGV.Width, DGV.Height) ‘ Temp Store For Bitmap

DGV.DrawToBitmap(b, New Rectangle(0, 0, DGV.ClientSize.Width, DGV.ClientSize.Height)) ‘ Copy the DataGrid to Bmp

PictureBox1.Image = b ‘ Show the bmp in image box control

و أرجو ان تكون الفكره قد وصلت و لو اخطأت بفهمك ارجو ان تبلغنى

و السلام عليكم و رحمة الله و بركاته

3 09 2008
alnabhani

اهلا بك اخي Black Fox وشكرا لك على التعقيب الرائع

لقد اشرت في التدوينه الى انني نقلت الكود “نقلاً” من موقع Codeproject وبالتالي فهي ليست لي .

عموما الفكرة التي وضحتها انت هي الافضل وذلك لانها تبقينا نتعامل مع ManagedCode بشكل دائم

تحياتي

13 09 2008
Black Fox

شكرا لك اخ نبهانى

لكن نصيحه

قبل ان تنقل شيئا خصوصا فيما يتعلق بالدوت نت حاول ان تتأكد انه مصمم بابسط و اكثر الطرق كفاءه

فليست الميزه فى استخدام DrawToBitmap فقط انها وفرت علينا استخدام اكواد غير مداره

بل ايضا انها صغرت حجم الكود بشكل رائع – و انها تم تصميمها خصيصا لهذا الغرض مما يؤدى بطبيعة الحال الى ان نتوقع انه تم عمل Optimization من فريق عمل مايكروسوفت عليها

احذر عزيزى من دوال API فهى اكثر خبثا مما تتصور

و رمضان كريم

29 05 2009
CoDe.NeT

شكرا جزيلا على الطريقة
طريقة أخرى

Private Sub pd_PrintPage(ByVal sender As Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
Handles pd.PrintPage
e.Graphics.DrawImage(formImage, 2, -200)
End Sub
Private Sub GetFormImage()
Dim g As Graphics = Me.CreateGraphics()
Dim s As Size = Me.Size
formImage = New Bitmap(s.Width, s.Height, g)
Dim mg As Graphics = Graphics.FromImage(formImage)
Dim dc1 As IntPtr = g.GetHdc
Dim dc2 As IntPtr = mg.GetHdc
‘ added code to compute and capture the form
‘ title bar and borders
Dim widthDiff As Integer = _
(Me.Width – Me.ClientRectangle.Width)
Dim heightDiff As Integer = _
(Me.Height – Me.ClientRectangle.Height)
Dim borderSize As Integer = widthDiff \ 2
Dim heightTitleBar As Integer = heightDiff – borderSize
BitBlt(dc2, 0, 0, _
Me.ClientRectangle.Width + widthDiff, _
Me.ClientRectangle.Height + heightDiff, dc1, _
0 – borderSize, 0 – heightTitleBar, 13369376)

g.ReleaseHdc(dc1)
mg.ReleaseHdc(dc2)
End Sub

‘زر طباعة

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

GetFormImage()
pd.Print()
End Sub

‘زر اختيار طابعة
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
GetFormImage()
PrintDialog1.Document = New PrintDocument
PrintDialog1.Document = pd

If PrintDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
pd.Print()

End If

End Sub
مع اضافة PrintDialog

29 05 2009
CoDe.NeT

التصدير الى اكسل

Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
‘ تصدير الى اكسل
Dim rowsTotal, colsTotal As Short
Dim I, j, iC As Short
System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor
Dim xlApp As New Excel.Application

Try
Dim excelBook As Excel.Workbook = xlApp.Workbooks.Add
Dim excelWorksheet As Excel.Worksheet = CType(excelBook.Worksheets(1), Excel.Worksheet)
xlApp.Visible = True
rowsTotal = DataGridView1.RowCount – 1
colsTotal = DataGridView1.Columns.Count – 1

With excelWorksheet
.Cells.Select()
.Cells.Delete()
For iC = 0 To colsTotal
.Cells(1, iC + 1).Value = DataGridView1.Columns(iC).HeaderText
Next

For I = 0 To rowsTotal – 1
For j = 0 To colsTotal – 1
.Cells(I + 2, j + 1).value = DataGridView1.Rows(I).Cells(j).Value
Next j
Next I

.Rows(“1:1″).Font.FontStyle = “Bold”
.Rows(“1:1″).Font.Size = 10
.Cells.Columns.AutoFit()
.Cells.Select()
.Cells.EntireColumn.AutoFit()
.Cells(1, 1).Select()
End With

Catch ex As Exception
MsgBox(“Export Excel Error ” & ex.Message)
Finally
‘RELEASE ALLOACTED RESOURCES
System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default
xlApp = Nothing
End Try
End Sub

مع اضافة السطر التالي كأول سطر
Imports Excel = Microsoft.Office.Interop.Excel
واضافة reference Microsoft.Office.Interop.Excel

29 05 2009
CoDe.NeT

تم تطبيق طريقة Black Fox ودمجها مع طريقتك وتؤدي نفس النتيجة بدون اضافة موديول

Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
Dim B As Bitmap = New Bitmap(DataGridView1.Width, DataGridView1.Height) ‘ Temp Store For Bitmap

DataGridView1.DrawToBitmap(B, New Rectangle(0, 0, DataGridView1.ClientSize.Width, DataGridView1.ClientSize.Height)) ‘ Copy the DataGrid to Bmp

Try
‘Open a file dialog for saving map documents
SaveFileDialog1.Title = “Save As BMP File”
SaveFileDialog1.Filter = “Bitmap File (*.bmp)|*.bmp”

If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
Exit Sub
End If

Catch ex As Exception

Exit Sub

End Try

‘Exit if no map document is selected
Dim sFilePath As String
sFilePath = SaveFileDialog1.FileName
If sFilePath = “” Then
Exit Sub
Else
B.Save(sFilePath)
End If

End Sub

شكرا جزيلا لكما

أضف تعليق