Horas!!!

Sebuah artikel tentang bagaimana membangun sebuah diary pribadi dengan WPF.

Introduction Pengenalan

Some people like to write down any event that occurs like their birthday or parties. Beberapa orang suka menuliskan peristiwa yang terjadi seperti ulang tahun mereka atau pihak. They record the event from the recording device and save it everywhere so it can easily get lost. Mereka merekam acara dari perangkat rekaman dan simpan di mana-mana sehingga dapat dengan mudah tersesat. This little software just helps to organize the event and organize the video. Software ini kecil hanya membantu untuk mengorganisir acara tersebut dan mengatur video.

Background Latar belakang

Windows Presentation Foundation (WPF) is a new technology from Microsoft that allows the developer to manipulate the user interface more easily. Windows Presentation Foundation (WPF) adalah sebuah teknologi baru dari Microsoft yang memungkinkan pengembang untuk memanipulasi user interface yang lebih mudah. The developer can act as a designer to build a user interface in a more interactive manner. Para pengembang dapat bertindak sebagai desainer untuk membangun sebuah antarmuka pengguna dengan cara yang lebih interaktif.
Until today, WPF does not have a property or method that handles stream data like MediaElement . MediaElement uses property Source to grab the media or streaming media; it cannot grab from byte [] or Stream . Sampai hari ini, WPF tidak memiliki properti atau metode yang menangani data stream seperti MediaElement . MediaElement menggunakan properti Source untuk ambil media atau streaming media; itu tidak bisa ambil dari byte [] atau Stream . It is not nice since it can come from many difference sources. Ini tidak baik karena dapat berasal dari sumber banyak perbedaan.

Requirement Kebutuhan

  • Windows XP with SP2 or Window Vista Windows XP dengan SP2 atau Window Vista
  • Microsoft Visual C# 2008 and Visual Web Developer 2008 Express Edition Microsoft Visual C # 2008 dan Visual Web Developer 2008 Express Edition
  • SQL Express 2005 with SP2 SQL Express 2005 dengan SP2
  • XCeed Component: Datagrid for WPF. Komponen XCeed: datagrid untuk WPF. You can download XCeed Component: Datagrid for WPF. Anda dapat men-download XCeed Komponen: datagrid untuk WPF. You can download it for free here Anda dapat men-download secara gratis di sini
  • Some videos with *.wmv extension to try these samples. Beberapa video dengan ekstensi *. wmv untuk mencoba sampel tersebut. I already tried with video having a maximum length of 100 MB Saya sudah mencoba dengan video memiliki panjang maksimum 100 MB

Prepare Everything Siapkan Semuanya

There are three files that need to be downloaded: Ada tiga file yang perlu didownload:
  1. Source code of Personal Diary WPF Source code Diary Pribadi WPF
  2. Source code of ASP.NET Source code dari ASP.NET
  3. An SQL file Sebuah file SQL
The source code of Personal Diary WPF is the main application. Kode sumber Diary Pribadi WPF adalah aplikasi utama. It can be opened using Visual C# 2008 Express Edition. Hal ini dapat dibuka dengan menggunakan Visual C # 2008 Express Edition.
The source code of ASP.NET as video stream is the ASP.NET that can only produce the media streaming. Kode sumber ASP.NET sebagai aliran video adalah ASP.NET yang hanya dapat menghasilkan media streaming. For now I only produce Windows Video ( *.wmv ) and MPEG video ( *.mpg ). Untuk saat ini saya hanya memproduksi Windows Video (*. wmv) dan video MPEG (*. mpg). It can be opened using Visual Web Developer 2008 Express Edition. Hal ini dapat dibuka dengan menggunakan Visual Web Developer 2008 Express Edition.
An SQL file can be opened using SQL Server Management Studio Express. SQL File dapat dibuka menggunakan SQL Server Management Studio Express. My database name is persdiary . nama database saya persdiary. You can change it and don't forget to change the connection string in the app.config . Anda dapat mengubahnya dan jangan lupa untuk mengubah connection string di app.config tersebut. Run the SQL so that the tables are ready to use. Jalankan SQL sehingga tabel siap digunakan.
Open both projects - WPF project and Web site. Buka kedua proyek - proyek WPF dan situs Web. Since not all windows installation equips with IIS, I use a built-in web server that comes with the product. Karena tidak semua instalasi windows melengkapi dengan IIS, saya menggunakan built-in web server yang datang dengan produk tersebut. Run the website first to make sure the Web server up and running. Jalankan situs web pertama untuk memastikan server Web dan berjalan.
menjalankan proyek situs Web After the website runs and the browser shows the result, copy the address URL from the browser to the value in the appSetting and find the key of hostpath. Setelah menjalankan situs web dan browser menunjukkan hasilnya, salin alamat URL dari browser dengan nilai di appSetting dan menemukan kunci hostpath.

Code from Webstream Website Project Kode dari Webstream Website Proyek

Since MediaElement control with Source property from WPF cannot receive byte [] or Stream , we can manipulate it using ASP.NET as a video stream. Sejak kontrol MediaElement dengan Source properti dari WPF tidak dapat menerima byte [] atau Stream , kita dapat memanipulasi dengan menggunakan ASP.NET sebagai aliran video. First ASP.NET will load the data from the database. Pertama ASP.NET akan memuat data dari database. The video itself saves in the varbinary data types in the mstvideo table. Video itu sendiri menyimpan dalam varbinary tipe data dalam mstvideo tabel.

On the Page Load Method Pada Metode Load Halaman

Collapse
if (Request.QueryString.Count > 0 ) if (Request.QueryString.Count> 0)
{ (
   string videoid = Request.QueryString[ " vid" ]; string videoid = Request.QueryString ["vid"];
   if (!string.IsNullOrEmpty(videoid)) if (! string.IsNullOrEmpty (videoid))
   { (
       bool loadFull = false ; bool loadFull = false;
       string loadFullStr = Request.QueryString[ " loadfull" ]; string loadFullStr = Request.QueryString ["loadfull"];
       if (!string.IsNullOrEmpty(loadFullStr)) loadFull = Convert.ToBoolean(loadFullStr); if (! string.IsNullOrEmpty (loadFullStr)) loadFull = Convert.ToBoolean (loadFullStr);
       else lain
       { (
           Response.Write( " 

Full Load or not?

"
);
Response.Write ("Load Kendali

atau tidak? "); } ) byte [] result = ReadVideo(videoid, loadFull); ] Hasil [byte = ReadVideo (videoid, loadFull); WriteVideoToPage(result); WriteVideoToPage (hasil); } ) else lain { ( Response.Write( "

Need Video ID

"
);
Response.Write ("Video

Perlu ID "); } ) } ) else lain { ( Response.Write( "

Need Video ID

"
); Response.Write ("Video

Perlu ID "); } )

This code will detect the query string and call the method to query data from the database and write the result to this page. Kode ini akan mendeteksi string kueri dan pemanggilan metode untuk query data dari database dan menulis hasil ke halaman ini. There are only two query strings: vid and loadfull . Hanya ada dua string query: vid dan loadfull . Query string vid is a video id that is useful to load video data by video id from the table. Query string vid adalah id video yang berguna untuk mengambil data video dengan video id dari meja. Query string loadfull is a flag not to load the video fully; in this case I will load 1/8th of total bytes received from the table. Query string loadfull adalah sebuah bendera tidak untuk memuat video sepenuhnya; dalam hal ini saya akan memuat 1/8th total byte yang diterima dari meja.

On the ReadVideo Method Pada Metode ReadVideo

Collapse
using (SqlConnection connection = new SqlConnection(ConnectionString)) menggunakan (koneksi SqlConnection SqlConnection baru = (ConnectionString))
{ (
    connection. Open (); koneksi). Terbuka (;
    SqlCommand command = connection.CreateCommand(); SqlCommand command = connection.CreateCommand ();
    command.CommandType = CommandType.Text; command.CommandType = CommandType.Text;
    StringBuilder sb = new StringBuilder(); StringBuilder sb = StringBuilder baru ();
    sb.Append( " SELECT " ); sb.Append ("SELECT");
    sb.Append( " DATALENGTH(vdcontent) AS vdcontent_length, " ); sb.Append ("DATALENGTH vdcontent () AS vdcontent_length,");
    sb.Append( " vdcontent,vdformat " ); sb.Append ("vdcontent, vdformat");
    sb.Append( " FROM mstvideo " ); sb.Append ("DARI mstvideo");
        sb.Append( " WHERE vdid=@vdid " ); sb.Append ("WHERE vdid = @ vdid");
    command.CommandText = sb.ToString(); command.CommandText = sb.ToString ();
    command.Parameters. Add ( " @vdid" , SqlDbType. Char ).Value = videoid; command.Parameters. Add ("@" vdid, SqlDbType. Char) =. Nilai videoid;
    using (SqlDataReader reader = command.ExecuteReader()) menggunakan (SqlDataReader reader = command.ExecuteReader ())
        int startIdx = 0; startIdx int = 0;
        long retval = 0; panjang retval = 0;
        if (!reader.HasRows) if (! reader.HasRows)
         { (
             Response.Write( " 

Don't have rows !

"
);
Response.Write ("

Jangan baris>! } ) while (reader. Read ()) sementara (reader. Baca ()) { ( if (string.Compare(reader.GetString(reader.GetOrdinal if (string.Compare (reader.GetString (reader.GetOrdinal ( " vdformat" )), " .wmv" ,true)==0) ("Vdformat")), ". Rar", true) == 0) Response.ContentType = " video/x-ms-wmv" ; Response.ContentType = "video / x-ms-wmv"; else if (string.Compare(reader.GetString lain jika (string.Compare (reader.GetString (reader.GetOrdinal( " vdformat" )), " .mpg" ,true)==0) (Reader.GetOrdinal ("vdformat")), "). Mpg", benar == 0) Response.ContentType = " video/mpeg" ; Response.ContentType = "video / mpeg"; int buffersize = reader.GetInt32(reader.GetOrdinal( " vdcontent_length" )); buffersize int = reader.GetInt32 (reader.GetOrdinal ("vdcontent_length")); if (!loadFull) if (! loadFull) buffersize /= 8; buffersize / = 8; movieContainer = new byte[buffersize]; movieContainer = baru [byte buffersize]; retval =reader.GetBytes(reader.GetOrdinal( " vdcontent" ), startIdx, retval = reader.GetBytes (reader.GetOrdinal ("vdcontent"), startIdx, movieContainer, 0 , buffersize); movieContainer, 0, buffersize); } ) } ) } )

The code above queries the video from the table. Kode di atas permintaan video dari meja. The select statement DATALENGTH(vdcontent) measures the length of data that is stored in vdcontent . Pernyataan pilih DATALENGTH(vdcontent) mengukur panjang data yang disimpan di vdcontent . I use command.ExecuteReader() to execute the query. Saya menggunakan command.ExecuteReader() untuk mengeksekusi query. The result is the length of the video, the video itself and the video format. Hasilnya adalah panjang video, video itu sendiri dan format video. The video format is useful to choose the MIME type of the ASP.NET. Format video yang berguna untuk memilih tipe MIME dari ASP.NET itu. For now, I only support WMV and MPG. Untuk saat ini, saya hanya mendukung WMV dan MPG. Again if loadfull is false , then I set the buffersize smaller; in this case I only divide the size by 8. Sekali lagi jika loadfull adalah false , maka saya mengatur buffersize lebih kecil, dalam hal ini saya hanya membagi ukuran dengan 8.

On the WriteVideoToPage Method Pada Metode WriteVideoToPage

Response.BufferOutput = true ; Response.BufferOutput = true;
 // Response.BinaryWrite(movieContents); / / Response.BinaryWrite (movieContents);
 BinaryWriter binWriter = new BinaryWriter(Response.OutputStream); BinaryWriter binWriter = BinaryWriter baru (Response.OutputStream);
 binWriter.Write(videoData); binWriter.Write (videoData);
 binWriter.Flush(); binWriter.Flush (); 
ASP.NET will render the video by writing the contents using System.IO.BinaryWriter . ASP.NET akan membuat video dengan menulis isinya menggunakan System.IO.BinaryWriter . The ASPX file itself is empty. The ASPX file itu sendiri adalah kosong.
 RegistryKey regKey = Registry.CurrentUser; RegistryKey regKey = Registry.CurrentUser;
 regKey = regKey.OpenSubKey( " Software" ); regKey = regKey.OpenSubKey ("Perangkat Lunak");
 regKey = regKey.OpenSubKey( " Nicko" ); regKey = regKey.OpenSubKey ("Nicko");
 if (regKey != null ) if (regKey! = null)
 { (
     result = regKey.GetValue( " ConnectionString" ).ToString(); Hasil = regKey.GetValue ("ConnectionString")). ToString (;
 } ) 
I use the registry key to get the connection string. Saya menggunakan kunci registri untuk mendapatkan string koneksi. So you can change the connection string once in the WPF app.config . Sehingga Anda dapat mengubah koneksi string sekali dalam app.config WPF.

Code from Personal Diary WPF Project Kode dari Personal Diary WPF Proyek

This is the main application that is written in WPF. Ini adalah aplikasi utama yang tertulis dalam WPF. The application can add a diary event and the video. Aplikasi ini dapat menambahkan acara buku harian dan video. You can click the video in the list below to enlarge the video to the center. Anda dapat mengklik video dalam daftar di bawah ini untuk memperbesar video ke pusat. Don't forget to add a reference to XCeed datagrid for WPF to make this work. Jangan lupa untuk menambahkan referensi ke XCeed datagrid untuk WPF untuk membuat karya ini.
First I add two new namespaces in MainWindow.xaml - The XCeed datagrid and local namespace: Pertama saya menambahkan dua ruang nama baru di MainWindow.xaml - The datagrid XCeed dan ruang nama lokal:
xmlns:local="clr-namespace:Diary.WPF" xmlns: lokal = "clr-namespace: Diary.WPF"
xmlns:xceed="clr-namespace:Xceed.Wpf.DataGrid;assembly=Xceed.Wpf.DataGrid" xmlns: xceed = "clr-namespace: Xceed.Wpf.DataGrid; perakitan = Xceed.Wpf.DataGrid" 
I add the Xceed datagrid to the grid layout: Aku menambahkan datagrid Xceed untuk layout grid:
< xceed:DataGridControl HorizontalAlignment =" Left" Margin =" 10,10,0,0"  DataGridControl HorizontalAlignment = "Waktu" Margin = "10,10,0,0"
 x:Name =" dgvEvents" VerticalAlignment =" Top" Width =" 380" x: Name = "dgvEvents" VerticalAlignment = "Top" Lebar = "380"
 MaxHeight =" 180" Height =" 180" SelectionMode =" Single" AutoCreateColumns =" False" MaxHeight = "180" Height = "180" SelectionMode = "Single" AutoCreateColumns = "Salah"
 NavigationBehavior =" RowOnly" TabIndex =" 0" ReadOnly =" True" NavigationBehavior = "RowOnly" TabIndex = "0" Readonly = "Benar"
 Mouse.MouseUp =" Datagrid_MouseUp" Keyboard.KeyUp =" DataGrid_KeyUp" > Mouse.MouseUp = "Datagrid_MouseUp" Keyboard.KeyUp = "DataGrid_KeyUp">
 < xceed:DataGridControl.Columns > 
 < xceed:Column FieldName =" EvDate" VisiblePosition =" 0" Title =" Date " Width =" 80" / >  Kolom FieldName = "EvDate" VisiblePosition = "0" Judul = "Tanggal" Lebar = "80" />
 < xceed:Column FieldName =" EvName" VisiblePosition =" 1" Title =" Name" Width =" 80"  Kolom FieldName = "EvName" = VisiblePosition "1" Judul = "Nama" Lebar = "80"
    TextWrapping =" Wrap" / > Teks rata = "Bungkus" />
 < xceed:Column FieldName =" EvStories" VisiblePosition =" 2" Title =" Stories"  Kolom FieldName = "EvStories" VisiblePosition = "2" Judul = "Stories"
    TextWrapping =" Wrap" Width =" 190" / > Teks rata = "Bungkus" Lebar = "190" />
 < / xceed:DataGridControl.Columns >  Xceed: DataGridControl.Columns>
 < / xceed:DataGridControl >  Xceed: DataGridControl> 
The grid will change the selected item when the mouse is clicked and keyboard is pressed up and down. grid akan mengubah item yang dipilih saat mouse diklik dan keyboard ditekan atas dan ke bawah. It will trigger to refresh the video content. Ini akan memicu untuk me-refresh konten video.
private void Datagrid_MouseUp( object sender, MouseButtonEventArgs e) swasta void Datagrid_MouseUp (pengirim objek, MouseButtonEventArgs e)
 { (
     RefreshContents(); RefreshContents ();
 } )
.... ....

private void DataGrid_KeyUp( object sender, KeyEventArgs e) swasta void DataGrid_KeyUp (pengirim objek, KeyEventArgs e)
{ (
       if (e.Key == Key.Up || e.Key == Key.Down) if (e.Key Key.Up == | | == e.Key Key.Down)
       { (
           RefreshContents(); RefreshContents ();
       } )
} ) 
I add the buttons that have a function to add event and add video. Aku menambahkan tombol yang memiliki fungsi untuk menambahkan event dan menambahkan video.
... ...
< Button Height =" 23" x:Name =" btnAddEvent" Width =" 30"  Tinggi = "23" x: Name = "btnAddEvent" Lebar = "30"
        Click =" btnAddEvent_Click" > Add < / Button > Klik = "btnAddEvent_Click" Tambah> Button>
... ...
< Button x:Name =" btnAddNewVideo" Click =" btnAddNewVideo_Click" > Add new < / Button >  x: Name = "btnAddNewVideo" Klik = "btnAddNewVideo_Click"> Tambah Tombol> 
The button will trigger an event to open a dialog window. Tombol akan memicu suatu peristiwa untuk membuka jendela dialog.
private void btnAddEvent_Click( object sender, RoutedEventArgs e) btnAddEvent_Click swasta void (pengirim objek, RoutedEventArgs e)
{ (
 ... ...
 bool ? bool? result = dlgInsert.ShowDialog(); Hasil = dlgInsert.ShowDialog ();
 ... ...
} )
} ) 
The method will open the new event dialog window: Metode yang akan membuka jendela dialog acara baru:


private void btnAddNewVideo_Click( object sender, RoutedEventArgs e) btnAddNewVideo_Click swasta void (pengirim objek, RoutedEventArgs e)
 { (
 ... ...
 bool ? bool? result = dlgVideo.ShowDialog(); Hasil = dlgVideo.ShowDialog ();
 ... ...
 } ) 
The method will open the new video dialog window: Metode yang akan membuka jendela dialog video baru:
When I click one of the videos below, the video will enlarge in the middle and play the video in full. Ketika saya klik salah satu video di bawah ini, video akan memperbesar di tengah dan memutar video secara penuh. When I click that large video, it will go back to the list below: Ketika saya klik yang video besar, itu akan kembali ke daftar di bawah ini:
private void me_MouseUp( object sender, MouseButtonEventArgs e) me_MouseUp swasta void (pengirim objek, MouseButtonEventArgs e)
 MediaElement me = sender as MediaElement; MediaElement saya = pengirim sebagai MediaElement;
 if (stkpanVideo.Children.IndexOf(me) >= 0 ) if (stkpanVideo.Children.IndexOf (aku)> = 0)
 { (
 // Quick and Dirty / / Cepat dan Dirty
  ... ...
 me.Height *= 4 ; me.Height *= 4;
 me.Width *= 4 ; me.Width *= 4;
  ... ...
 } )
 else lain
 { (
 // Quick and Dirty / / Cepat dan Dirty
 ... ...
 me.Height /= 4 ; me.Height / = 4;
 me.Width /= 4 ; me.Width / = 4;
 ... ...
 } )
} ) 
I create an XAML to act as a window dialog to add events to the table. Aku membuat XAML untuk bertindak sebagai jendela dialog untuk menambahkan event ke meja. It is Insert InsertEventDialog.xaml . Hal ini InsertEventDialog.xaml Sisipkan. I use a grid layout to create a table-like layout with textblocks and textboxes as input controls. Saya menggunakan layout grid untuk membuat tata letak meja seperti dengan textblocks dan textboxes sebagai kontrol input. I use a Windows Form DateTimePicker to choose event date. Saya menggunakan Windows Formulir DateTimePicker untuk memilih event date. I create InsertNewVideo.xaml to add a video for the selected diary event. Cara membuat InsertNewVideo.xaml untuk menambahkan video untuk acara buku harian yang dipilih.
... ...
    ... ...
< TextBlock ... / >  ... />
< TextBox ... / >  ... />
... ...
< WindowsFormsHost Name =" wpfHost" >  Nama = "wpfHost">
    < windowsform:DateTimePicker ...  WindowsFormsHost >  DateTimePicker ... WindowsFormsHost> 

Points of Interest Poin Kepentingan

I learnt how to bind data to the WPF control using the ObservableCollection < of T > , not only Dataset or Datatable . Saya belajar cara mengikat data ke kontrol WPF menggunakan ObservableCollection < of T > , tidak hanya Dataset atau Datatable . I just write the property name to the binding source in the control property and automatically bind. Aku hanya menulis nama properti ke sumber yang mengikat dalam properti kontrol dan secara otomatis mengikat.
ASP.NET can be used as a streaming video source, so I can use it as a dynamic source for MediaElement . ASP.NET dapat digunakan sebagai sumber video streaming, sehingga saya dapat menggunakannya sebagai sumber yang dinamis untuk MediaElement .

History Sejarah

  • Version 1.0: 28 December 2007 - Application released Versi 1.0: 28 Desember 2007 - Aplikasi dirilis

License Lisensi

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL) Artikel ini, bersama dengan kode sumber yang terkait dan file apapun, dilisensikan di bawah Kode Proyek Open License (CPOL)

Categories: