Benutzer mit den meisten Antworten
Umblättern

Frage
-
Hallo,
ich habe nochmal eine Frage zu einer animation und zwar das Umblättern einer Seite, denn ich will ein Buch simulieren. Meine Frage ist jetzt, wie das geht, besonders das mit Vor- und Rückseite.
Ich wäre über eine kleine Anleitung sehr dankbar
ClionelSamstag, 24. Oktober 2009 10:28
Antworten
-
Hallo Clionel,
schau dir mal folgendes Projekt auf Codeplex an:
http://wpfbookcontrol.codeplex.com/
Schöne Grüße
Oliver- Als Antwort vorgeschlagen Robert Breitenhofer Dienstag, 3. November 2009 12:15
- Als Antwort markiert Robert Breitenhofer Freitag, 6. November 2009 15:32
Samstag, 24. Oktober 2009 14:05 -
Hallo clionel,
Lies bitte durch auch den folgenden Artikel. Vielleicht kann er Dir weiter helfen.
http://msdn.microsoft.com/en-us/magazine/cc507644.aspx
Grüße,
Robert
- Als Antwort vorgeschlagen Robert Breitenhofer Dienstag, 3. November 2009 12:15
- Als Antwort markiert Robert Breitenhofer Freitag, 6. November 2009 15:32
Donnerstag, 29. Oktober 2009 09:57 -
Hi Clionel,
da ich mich am Wochenende gerade selbst mit dem Silverlight Book Control von Mitsu befaßt habe, kann ich Dir ein Sourcecode Beispiel in VB.NET geben. Die Sample Application von Mitsu ist in C#, ich programmiere in VB.NET. Deswegen mag das folgende Beispiel in VB.NET Code auch eine Hilfe für andere VB.NET Programmierer sein, wenn Sie keine Lust haben, die Beispielanwendung von Mitsu aus C# in VB.NET zu übersetzen.
Ein Hinweis vorab: Ich programmiere derzeit Silverlight 2 in VS 2008, .NET 3.5 SP1.
Als erstes brauchst Du einen Verweis auf die Datei SLMitsuControls.dll. Dann in der Page.xaml einen Verweis auf den Namespace:
xmlns:local="clr-namespace:SLMitsuControls;assembly=SLMitsuControls"
und in der Page.xaml.vb eine Imports-Anweisung:Imports SLMitsuControls
Dann wird direkt im Grid Layoutroot ein UCBook Control eingefügt:
<local:UCBook x:Name="book" Margin="20" Height="760" Width="1200"/>
Das UCBook Control hat wie Du siehst feste Größenangaben und nur eine Margin. Für die Page sind Width und Height im XAML auf Auto gesetzt.
Rebuild your solution und dann ab in den Code behind für die Einrichtung der Seiten des UCBook, dem ich den Namen "book" gegeben habe.
In der Code Behind Datei muss die Schnittstelle IDataProvider von Mitsu's BookControl einbezogen werden. Das erfolgt über die folgende Anweisung:Implements IDataProvider
die bekanntlich direkt unter die Anweisung:Inherits UserControl
eingefügt werden muss. Dabei ist es nach meiner Erfahrung wichtig, dass die Anweisung Implements IDataProvider nicht einfach per Copy Paste eingefügt, sondern selbst eingetippt und mit Return ein Zeilenwechsel eingefügt wird, weil dann automatisch die entsprechenden (leeren) Routinen zur Verarbeitung der Schnittstelle mit den Signaturen eingefügt werden:Public Function GetCount() As Integer Implements SLMitsuControls.IDataProvider.GetCount End Function Public Function GetItem(ByVal index As Integer) As Object Implements SLMitsuControls.IDataProvider.GetItem End Function
Der Code dieser Routinen muss dann wie folgt ergänzt werden:Public Function GetCount() As Integer Implements SLMitsuControls.IDataProvider.GetCount Return pages.Count End Function Public Function GetItem(ByVal index As Integer) As Object Implements SLMitsuControls.IDataProvider.GetItem Return pages(index) End Function
Teilweise muckte VS herum, wenn ich die Routinen, z.B. aus einem anderen Projekt, einfach per Copy/Paste übernommen habe. Deswegen meine hierzu empfohlene obige Vorgehensweise.
Für die in den beiden Routinen verarbeiteten "pages" brauchst Du noch eine generische Private List (Of IrgendeinControl). Sinnvollerweise nimmt man eine List (Of Grid), um einen Container bereitzustellen, der dann weitere UIElemente aufnehmen kann, die später auf den einzelnen pages jeweils enthalten sein sollen:Private pages As List(Of Grid)
Dann fehlt noch eine Routine für das LoadedEvent des UCBook, in diesem Beispiel also book_Loaded(...):Private Sub book_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles book.Loaded ' Code hinzufügen, der die Pages gestaltet. End Sub
In dieser Routine - oder ausgelagert in dienende Functions - baut man dann die Gestaltung der einzelnen Pages ein. In diesem Beispiel habe ich als Container einer Buchseite jeweils ein Grid gewählt, indem ich die generische Liste pages als List (OfGrid) definiert habe. Du kannst aber die generische Liste z.B. auch aus Stackpanels oder Canvas bilden. Denkbar ist auch, dass Du ein einzelnen UIElement nimmst, z.B. einen Button oder ein Image. Dann kannst Du aber natürlich keine Child-Elemente einfügen.
Jedes Grid eines der pages bildet also im Beispiel das oberste UIElement einer jeweiligen Buchseite. In jedes Grid können die einzelnen Steuerelemente als Child-Elemente eingebaut werden. Das kann z.B. so aussehen:Private Sub book_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles book.Loaded ' Code hinzufügen, der die Pages gestaltet. pages = New List(Of Grid) For i As Integer = 1 To 4 pages.Add(BuildPage(i)) Next book.SetData(Me) End Sub Private Function BuildPage(ByVal pagina As Integer) As Grid Dim result As New Grid Dim bd As New Border With bd .BorderBrush = New SolidColorBrush(Colors.Gray) .BorderThickness = New Thickness(2) .CornerRadius = New CornerRadius(5) .Background = New SolidColorBrush(Colors.Black) .Margin = New Thickness(16) .VerticalAlignment = Windows.VerticalAlignment.Top .Height = 500 End With Dim tb As New TextBlock With {.Text = " Dies ist Seite " + pagina.ToString + ".", _ .Height = 30, _ .FontSize = 26, _ .Foreground = New SolidColorBrush(Colors.Brown)} bd.Child = tb With result .Height = 760 .Background = New SolidColorBrush(Colors.Brown) .HorizontalAlignment = Windows.HorizontalAlignment.Stretch .VerticalAlignment = Windows.VerticalAlignment.Stretch .Children.Add(bd) End With Return result End Function
Rebuild your solution, F5 und voila ... das Buch ist gebunden.
Damit die Seiten auch beim Click des Users auf eine Seite reagieren, müssen noch zwei Routinen her:Private Sub NächsteSeite(ByVal sender As Object, ByVal e As RoutedEventArgs) book.AnimateToNextPage(500) End Sub Private Sub VorherigeSeite(ByVal sender As Object, ByVal e As RoutedEventArgs) book.AnimateToPreviousPage(700) End Sub
auf die dann in der Routine book_Loaded noch ein Zugriff per AddHandler eingebaut werden muss. Die fertige book_Loaded sieht dann so aus:Private Sub book_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles book.Loaded ' Code hinzufügen, der die Pages gestaltet. pages = New List(Of Grid) For i As Integer = 1 To 4 pages.Add(BuildPage(i)) Next ' Handler für das Blättern per Click auf eine Buchseite einfügen: Dim c As Integer = 0 For Each b As Grid In pages If ((c Mod 2) = 0) Then AddHandler b.MouseLeftButtonUp, AddressOf NächsteSeite Else AddHandler b.MouseLeftButtonUp, AddressOf VorherigeSeite End If c = (c + 1) Next book.SetData(Me) End Sub
Das war's.
Wenn Du jetzt noch auf den Wechsel von Seiten reagieren willst, dann geht das über die UCBook Methode OnPageTurned, in der Du dann die Parameter leftPageIndex und/oder rightPageIndex auswerten kannst, um festzustellen, von welcher Seite auf welche Seite gewechselt wurde. Dabei hat die erste in der UI sichtbare Seite den leftPageIndex -1, die zweite in der UI sichtbare Seite aber den leftPageIndex 2.
Wenn Du mehr über die Mathematik eines BookControls und die Umsetzung der Algorithmen in Code erfahren willst, dann bietet der folgende Link einen auch visuell super umgesetzten instruktiven Zugang. Unter dem Link kann man auch den Sourcecode eines Silverlight 3 Beispiels herunterladen:
http://www.cynergysystems.com/blogs/page/rickbarraza?entry=the_secret_behind_the_page
Ich hoffe, das war hilfreich. Wenn Du noch Fragen hast, dann poste hier.
Beste Grüße,
M. (LawBot)
Nachtrag:
Um möglichst flexibel bei der Gestaltung der einzelnen Buchseiten zu bleiben, empfiehlt es sich, die pages As List(Of UIElement) zu definieren. Dadurch kann man dann jedes Steuerelement das von UIElement erbt, als oberstes Element einer page zuordnen. Man muss dann also nicht mehr die UIElemente einer jeden Seite unbedingt in ein Grid einbinden (auch wenn das meistens ausreicht), sondern kann als oberstes UIElement z.B. auf Seite 1 ein Image, auf Seite 2 ein Grid, auf Seite 3 einen Button, usw. unterbringen.
Beste Grüße,
M.- Als Antwort vorgeschlagen Martin Krüger Donnerstag, 19. November 2009 23:32
- Als Antwort markiert Robert Breitenhofer Freitag, 20. November 2009 07:28
- Bearbeitet Martin Krüger Mittwoch, 9. Dezember 2009 18:02 Nachtrag
Donnerstag, 19. November 2009 23:03
Alle Antworten
-
Hallo Clionel,
schau dir mal folgendes Projekt auf Codeplex an:
http://wpfbookcontrol.codeplex.com/
Schöne Grüße
Oliver- Als Antwort vorgeschlagen Robert Breitenhofer Dienstag, 3. November 2009 12:15
- Als Antwort markiert Robert Breitenhofer Freitag, 6. November 2009 15:32
Samstag, 24. Oktober 2009 14:05 -
Hallo clionel,
Lies bitte durch auch den folgenden Artikel. Vielleicht kann er Dir weiter helfen.
http://msdn.microsoft.com/en-us/magazine/cc507644.aspx
Grüße,
Robert
- Als Antwort vorgeschlagen Robert Breitenhofer Dienstag, 3. November 2009 12:15
- Als Antwort markiert Robert Breitenhofer Freitag, 6. November 2009 15:32
Donnerstag, 29. Oktober 2009 09:57 -
Hi Clionel,
da ich mich am Wochenende gerade selbst mit dem Silverlight Book Control von Mitsu befaßt habe, kann ich Dir ein Sourcecode Beispiel in VB.NET geben. Die Sample Application von Mitsu ist in C#, ich programmiere in VB.NET. Deswegen mag das folgende Beispiel in VB.NET Code auch eine Hilfe für andere VB.NET Programmierer sein, wenn Sie keine Lust haben, die Beispielanwendung von Mitsu aus C# in VB.NET zu übersetzen.
Ein Hinweis vorab: Ich programmiere derzeit Silverlight 2 in VS 2008, .NET 3.5 SP1.
Als erstes brauchst Du einen Verweis auf die Datei SLMitsuControls.dll. Dann in der Page.xaml einen Verweis auf den Namespace:
xmlns:local="clr-namespace:SLMitsuControls;assembly=SLMitsuControls"
und in der Page.xaml.vb eine Imports-Anweisung:Imports SLMitsuControls
Dann wird direkt im Grid Layoutroot ein UCBook Control eingefügt:
<local:UCBook x:Name="book" Margin="20" Height="760" Width="1200"/>
Das UCBook Control hat wie Du siehst feste Größenangaben und nur eine Margin. Für die Page sind Width und Height im XAML auf Auto gesetzt.
Rebuild your solution und dann ab in den Code behind für die Einrichtung der Seiten des UCBook, dem ich den Namen "book" gegeben habe.
In der Code Behind Datei muss die Schnittstelle IDataProvider von Mitsu's BookControl einbezogen werden. Das erfolgt über die folgende Anweisung:Implements IDataProvider
die bekanntlich direkt unter die Anweisung:Inherits UserControl
eingefügt werden muss. Dabei ist es nach meiner Erfahrung wichtig, dass die Anweisung Implements IDataProvider nicht einfach per Copy Paste eingefügt, sondern selbst eingetippt und mit Return ein Zeilenwechsel eingefügt wird, weil dann automatisch die entsprechenden (leeren) Routinen zur Verarbeitung der Schnittstelle mit den Signaturen eingefügt werden:Public Function GetCount() As Integer Implements SLMitsuControls.IDataProvider.GetCount End Function Public Function GetItem(ByVal index As Integer) As Object Implements SLMitsuControls.IDataProvider.GetItem End Function
Der Code dieser Routinen muss dann wie folgt ergänzt werden:Public Function GetCount() As Integer Implements SLMitsuControls.IDataProvider.GetCount Return pages.Count End Function Public Function GetItem(ByVal index As Integer) As Object Implements SLMitsuControls.IDataProvider.GetItem Return pages(index) End Function
Teilweise muckte VS herum, wenn ich die Routinen, z.B. aus einem anderen Projekt, einfach per Copy/Paste übernommen habe. Deswegen meine hierzu empfohlene obige Vorgehensweise.
Für die in den beiden Routinen verarbeiteten "pages" brauchst Du noch eine generische Private List (Of IrgendeinControl). Sinnvollerweise nimmt man eine List (Of Grid), um einen Container bereitzustellen, der dann weitere UIElemente aufnehmen kann, die später auf den einzelnen pages jeweils enthalten sein sollen:Private pages As List(Of Grid)
Dann fehlt noch eine Routine für das LoadedEvent des UCBook, in diesem Beispiel also book_Loaded(...):Private Sub book_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles book.Loaded ' Code hinzufügen, der die Pages gestaltet. End Sub
In dieser Routine - oder ausgelagert in dienende Functions - baut man dann die Gestaltung der einzelnen Pages ein. In diesem Beispiel habe ich als Container einer Buchseite jeweils ein Grid gewählt, indem ich die generische Liste pages als List (OfGrid) definiert habe. Du kannst aber die generische Liste z.B. auch aus Stackpanels oder Canvas bilden. Denkbar ist auch, dass Du ein einzelnen UIElement nimmst, z.B. einen Button oder ein Image. Dann kannst Du aber natürlich keine Child-Elemente einfügen.
Jedes Grid eines der pages bildet also im Beispiel das oberste UIElement einer jeweiligen Buchseite. In jedes Grid können die einzelnen Steuerelemente als Child-Elemente eingebaut werden. Das kann z.B. so aussehen:Private Sub book_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles book.Loaded ' Code hinzufügen, der die Pages gestaltet. pages = New List(Of Grid) For i As Integer = 1 To 4 pages.Add(BuildPage(i)) Next book.SetData(Me) End Sub Private Function BuildPage(ByVal pagina As Integer) As Grid Dim result As New Grid Dim bd As New Border With bd .BorderBrush = New SolidColorBrush(Colors.Gray) .BorderThickness = New Thickness(2) .CornerRadius = New CornerRadius(5) .Background = New SolidColorBrush(Colors.Black) .Margin = New Thickness(16) .VerticalAlignment = Windows.VerticalAlignment.Top .Height = 500 End With Dim tb As New TextBlock With {.Text = " Dies ist Seite " + pagina.ToString + ".", _ .Height = 30, _ .FontSize = 26, _ .Foreground = New SolidColorBrush(Colors.Brown)} bd.Child = tb With result .Height = 760 .Background = New SolidColorBrush(Colors.Brown) .HorizontalAlignment = Windows.HorizontalAlignment.Stretch .VerticalAlignment = Windows.VerticalAlignment.Stretch .Children.Add(bd) End With Return result End Function
Rebuild your solution, F5 und voila ... das Buch ist gebunden.
Damit die Seiten auch beim Click des Users auf eine Seite reagieren, müssen noch zwei Routinen her:Private Sub NächsteSeite(ByVal sender As Object, ByVal e As RoutedEventArgs) book.AnimateToNextPage(500) End Sub Private Sub VorherigeSeite(ByVal sender As Object, ByVal e As RoutedEventArgs) book.AnimateToPreviousPage(700) End Sub
auf die dann in der Routine book_Loaded noch ein Zugriff per AddHandler eingebaut werden muss. Die fertige book_Loaded sieht dann so aus:Private Sub book_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles book.Loaded ' Code hinzufügen, der die Pages gestaltet. pages = New List(Of Grid) For i As Integer = 1 To 4 pages.Add(BuildPage(i)) Next ' Handler für das Blättern per Click auf eine Buchseite einfügen: Dim c As Integer = 0 For Each b As Grid In pages If ((c Mod 2) = 0) Then AddHandler b.MouseLeftButtonUp, AddressOf NächsteSeite Else AddHandler b.MouseLeftButtonUp, AddressOf VorherigeSeite End If c = (c + 1) Next book.SetData(Me) End Sub
Das war's.
Wenn Du jetzt noch auf den Wechsel von Seiten reagieren willst, dann geht das über die UCBook Methode OnPageTurned, in der Du dann die Parameter leftPageIndex und/oder rightPageIndex auswerten kannst, um festzustellen, von welcher Seite auf welche Seite gewechselt wurde. Dabei hat die erste in der UI sichtbare Seite den leftPageIndex -1, die zweite in der UI sichtbare Seite aber den leftPageIndex 2.
Wenn Du mehr über die Mathematik eines BookControls und die Umsetzung der Algorithmen in Code erfahren willst, dann bietet der folgende Link einen auch visuell super umgesetzten instruktiven Zugang. Unter dem Link kann man auch den Sourcecode eines Silverlight 3 Beispiels herunterladen:
http://www.cynergysystems.com/blogs/page/rickbarraza?entry=the_secret_behind_the_page
Ich hoffe, das war hilfreich. Wenn Du noch Fragen hast, dann poste hier.
Beste Grüße,
M. (LawBot)
Nachtrag:
Um möglichst flexibel bei der Gestaltung der einzelnen Buchseiten zu bleiben, empfiehlt es sich, die pages As List(Of UIElement) zu definieren. Dadurch kann man dann jedes Steuerelement das von UIElement erbt, als oberstes Element einer page zuordnen. Man muss dann also nicht mehr die UIElemente einer jeden Seite unbedingt in ein Grid einbinden (auch wenn das meistens ausreicht), sondern kann als oberstes UIElement z.B. auf Seite 1 ein Image, auf Seite 2 ein Grid, auf Seite 3 einen Button, usw. unterbringen.
Beste Grüße,
M.- Als Antwort vorgeschlagen Martin Krüger Donnerstag, 19. November 2009 23:32
- Als Antwort markiert Robert Breitenhofer Freitag, 20. November 2009 07:28
- Bearbeitet Martin Krüger Mittwoch, 9. Dezember 2009 18:02 Nachtrag
Donnerstag, 19. November 2009 23:03