Binäruhr

    • C#
    • .NET (FX) 4.5–4.8

    Es gibt 32 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

      Hi Forum,

      hab eben mal ne Binäruhr mit C# und WPF gezaubert.
      Wollte hier nur meinen Code bereitstellen, falls jemand Interesse daran hat :)

      Ich bin dankbar für Kritik und Verbesserungsvorschläge.

      Edit:
      Converter.cs

      C#-Quellcode

      1. using System;
      2. using System.Globalization;
      3. using System.Windows.Data;
      4. using System.Windows.Media;
      5. namespace BinaerUhrMVVM.Converters
      6. {
      7. [ValueConversion(typeof(bool),typeof(Brush))]
      8. public class Converter : IValueConverter
      9. {
      10. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      11. {
      12. if ((bool)value)
      13. return Brushes.Red;
      14. return Brushes.LightGray;
      15. }
      16. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      17. {
      18. throw new NotImplementedException();
      19. }
      20. }
      21. }



      ZeitSpeicher.cs

      C#-Quellcode

      1. using System;
      2. using System.ComponentModel;
      3. using System.Collections.ObjectModel;
      4. namespace BinaerUhrMVVM
      5. {
      6. public class ZeitSpeicher
      7. {
      8. public ObservableCollection<bool> H { get; private set; }
      9. public ObservableCollection<bool> M { get; private set; }
      10. public ObservableCollection<bool> S { get; private set; }
      11. public ZeitSpeicher()
      12. {
      13. H = new ObservableCollection<bool>(new bool[5]);
      14. M = new ObservableCollection<bool>(new bool[6]);
      15. S = new ObservableCollection<bool>(new bool[6]);
      16. }
      17. public void setTime(bool[] h, bool[] m, bool[] s)
      18. {
      19. for (int i = 0; i < 6; i++)
      20. {
      21. if(i < 5)
      22. this.H[i] = h[i];
      23. this.M[i] = m[i];
      24. this.S[i] = s[i];
      25. }
      26. }
      27. public bool[] toBinary(int time)
      28. {
      29. int tempTime = time;
      30. bool[] bits = new bool[6];
      31. for (int i = 0; i < 6; i++)
      32. {
      33. if ((tempTime / (1 << (5 - i))) > 0)
      34. {
      35. bits[i] = true;
      36. tempTime -= (1 << (5 - i));
      37. }
      38. else
      39. bits[i] = false;
      40. }
      41. Array.Reverse(bits);
      42. return bits;
      43. }
      44. public void act(DateTime time)
      45. {
      46. setTime(toBinary(time.Hour), toBinary(time.Minute), toBinary(time.Second));
      47. }
      48. }
      49. }



      UhrModel.cs

      C#-Quellcode

      1. using System;
      2. using System.Windows;
      3. using System.Windows.Threading;
      4. namespace BinaerUhrMVVM.ViewModel
      5. {
      6. internal class UhrModel
      7. {
      8. public UhrModel()
      9. {
      10. _time = new ZeitSpeicher();
      11. timer = new DispatcherTimer();
      12. timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
      13. timer.Tick += timer_Tick;
      14. timer.Start();
      15. }
      16. private ZeitSpeicher _time;
      17. public ZeitSpeicher time
      18. {
      19. get { return _time; }
      20. }
      21. private DispatcherTimer timer;
      22. void timer_Tick(object sender, EventArgs e)
      23. {
      24. _time.act(DateTime.Now);
      25. }
      26. }
      27. }



      Uhr.xaml

      XML-Quellcode

      1. <Window x:Class="BinaerUhrMVVM.MainWindow"
      2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      4. xmlns:vm="clr-namespace:BinaerUhrMVVM.ViewModel"
      5. xmlns:cnv="clr-namespace:BinaerUhrMVVM.Converters"
      6. Title="Binär-Uhr" Height="220" Width="140" KeyboardNavigation.TabNavigation="None" MinWidth="140" MinHeight="220" WindowStyle="ToolWindow" ResizeMode="NoResize" >
      7. <Window.Resources>
      8. <vm:UhrModel x:Key="uhr" />
      9. <cnv:Converter x:Key="boolToBrushConverter" />
      10. </Window.Resources>
      11. <StackPanel Orientation="Vertical" DataContext="{StaticResource uhr}" Width="110">
      12. <Grid Height="25">
      13. <Grid.ColumnDefinitions>
      14. <ColumnDefinition Width="25" />
      15. <ColumnDefinition Width="*" />
      16. <ColumnDefinition Width="*" />
      17. <ColumnDefinition Width="*" />
      18. </Grid.ColumnDefinitions>
      19. <TextBlock Grid.Column="1" Text="h" TextAlignment="Center" VerticalAlignment="Bottom"/>
      20. <TextBlock Grid.Column="2" Text="m" TextAlignment="Center" VerticalAlignment="Bottom"/>
      21. <TextBlock Grid.Column="3" Text="s" TextAlignment="Center" VerticalAlignment="Bottom"/>
      22. </Grid>
      23. <Grid>
      24. <Grid.ColumnDefinitions>
      25. <ColumnDefinition Width="25" />
      26. <ColumnDefinition Width="*" />
      27. <ColumnDefinition Width="*" />
      28. <ColumnDefinition Width="*" />
      29. </Grid.ColumnDefinitions>
      30. <ItemsControl Background="{x:Null}" BorderBrush="{x:Null}">
      31. <Label Content="1" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" Height="25"/>
      32. <Label Content="2" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" Height="25"/>
      33. <Label Content="4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" Height="25"/>
      34. <Label Content="8" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" Height="25"/>
      35. <Label Content="16" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" Height="25"/>
      36. <Label Content="32" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" Height="25"/>
      37. </ItemsControl>
      38. <ItemsControl Grid.Column="1" ItemsSource="{Binding time.H}" Background="{x:Null}" BorderBrush="{x:Null}">
      39. <ItemsControl.ItemTemplate>
      40. <DataTemplate>
      41. <Border Height="{Binding Width, RelativeSource={RelativeSource Self}}" Width="25" HorizontalAlignment="Stretch" Padding="4">
      42. <Border Background="{Binding BindsDirectlyToSource=True, Converter={StaticResource boolToBrushConverter}}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
      43. </Border>
      44. </DataTemplate>
      45. </ItemsControl.ItemTemplate>
      46. </ItemsControl>
      47. <ItemsControl Grid.Column="2" ItemsSource="{Binding time.M}" Background="{x:Null}" BorderBrush="{x:Null}">
      48. <ItemsControl.ItemTemplate>
      49. <DataTemplate>
      50. <Border Height="{Binding Width, RelativeSource={RelativeSource Self}}" Width="25" HorizontalAlignment="Stretch" Padding="4">
      51. <Border Background="{Binding BindsDirectlyToSource=True, Converter={StaticResource boolToBrushConverter}}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
      52. </Border>
      53. </DataTemplate>
      54. </ItemsControl.ItemTemplate>
      55. </ItemsControl>
      56. <ItemsControl Grid.Column="3" ItemsSource="{Binding time.S}" Background="{x:Null}" BorderBrush="{x:Null}">
      57. <ItemsControl.ItemTemplate>
      58. <DataTemplate>
      59. <Border Height="{Binding Width, RelativeSource={RelativeSource Self}}" Width="25" HorizontalAlignment="Stretch" Padding="4">
      60. <Border Background="{Binding BindsDirectlyToSource=True, Converter={StaticResource boolToBrushConverter}}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
      61. </Border>
      62. </DataTemplate>
      63. </ItemsControl.ItemTemplate>
      64. </ItemsControl>
      65. </Grid>
      66. </StackPanel>
      67. </Window>



      Screenshot:



      Danke an alle, die hier ihre Kritik abgegeben haben.
      Besonderen Dank an @ErfinderDesRades

      Viel Spaß mit dem Code, die Projektmappe findet ihr im Anhang.


      Alt

      Fenster (natürlich XAML, nicht XML :P ) :
      Spoiler anzeigen

      XML-Quellcode

      1. <Window x:Class="Binäruhr.MainWindow"
      2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      4. Title="Binär Uhr" Height="350" Width="192" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
      5. <Grid>
      6. <Grid.ColumnDefinitions>
      7. <ColumnDefinition Width="*" />
      8. <ColumnDefinition Width="30" />
      9. <ColumnDefinition Width="10" />
      10. <ColumnDefinition Width="30" />
      11. <ColumnDefinition Width="10" />
      12. <ColumnDefinition Width="30" />
      13. <ColumnDefinition Width="*" />
      14. </Grid.ColumnDefinitions>
      15. <Grid.RowDefinitions>
      16. <RowDefinition Height="*" />
      17. <RowDefinition Height="30" />
      18. <RowDefinition Height="10" />
      19. <RowDefinition Height="30" />
      20. <RowDefinition Height="10" />
      21. <RowDefinition Height="30" />
      22. <RowDefinition Height="10" />
      23. <RowDefinition Height="30" />
      24. <RowDefinition Height="10" />
      25. <RowDefinition Height="30" />
      26. <RowDefinition Height="10" />
      27. <RowDefinition Height="30" />
      28. <RowDefinition Height="10" />
      29. <RowDefinition Height="30" />
      30. <RowDefinition Height="2*" />
      31. </Grid.RowDefinitions>
      32. <TextBlock Text="h:" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
      33. <TextBlock Text="m:" Grid.Column="3" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
      34. <TextBlock Name="s_txt" Text="s:" Grid.Column="5" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
      35. <TextBlock Text="1:" Margin="0,0,10,0" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Column="0" Grid.Row="3" />
      36. <TextBlock Text="2:" Margin="0,0,10,0" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Column="0" Grid.Row="5" />
      37. <TextBlock Text="4:" Margin="0,0,10,0" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Column="0" Grid.Row="7" />
      38. <TextBlock Text="8:" Margin="0,0,10,0" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Column="0" Grid.Row="9" />
      39. <TextBlock Text="16:" Margin="0,0,10,0" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Column="0" Grid.Row="11" />
      40. <TextBlock Text="32:" Margin="0,0,10,0" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Column="0" Grid.Row="13" />
      41. <Border Background="Blue" Margin="5" Grid.Column="1" Grid.Row="3" Name="h1" />
      42. <Border Background="Blue" Margin="5" Grid.Column="1" Grid.Row="5" Name="h2" />
      43. <Border Background="Blue" Margin="5" Grid.Column="1" Grid.Row="7" Name="h4" />
      44. <Border Background="Blue" Margin="5" Grid.Column="1" Grid.Row="9" Name="h8" />
      45. <Border Background="Blue" Margin="5" Grid.Column="1" Grid.Row="11" Name="h16" />
      46. <Border Background="Blue" Margin="5" Grid.Column="3" Grid.Row="3" Name="m1" />
      47. <Border Background="Blue" Margin="5" Grid.Column="3" Grid.Row="5" Name="m2" />
      48. <Border Background="Blue" Margin="5" Grid.Column="3" Grid.Row="7" Name="m4" />
      49. <Border Background="Blue" Margin="5" Grid.Column="3" Grid.Row="9" Name="m8" />
      50. <Border Background="Blue" Margin="5" Grid.Column="3" Grid.Row="11" Name="m16" />
      51. <Border Background="Blue" Margin="5" Grid.Column="3" Grid.Row="13" Name="m32" />
      52. <Border Background="Blue" Margin="5" Grid.Column="5" Grid.Row="3" Name="s1" />
      53. <Border Background="Blue" Margin="5" Grid.Column="5" Grid.Row="5" Name="s2" />
      54. <Border Background="Blue" Margin="5" Grid.Column="5" Grid.Row="7" Name="s4" />
      55. <Border Background="Blue" Margin="5" Grid.Column="5" Grid.Row="9" Name="s8" />
      56. <Border Background="Blue" Margin="5" Grid.Column="5" Grid.Row="11" Name="s16" />
      57. <Border Background="Blue" Margin="5" Grid.Column="5" Grid.Row="13" Name="s32" />
      58. </Grid>
      59. </Window>



      Spoiler anzeigen

      C#-Quellcode

      1. using System;
      2. using System.Collections.Generic;
      3. using System.Linq;
      4. using System.Text;
      5. using System.Threading.Tasks;
      6. using System.Windows;
      7. using System.Windows.Controls;
      8. using System.Windows.Data;
      9. using System.Windows.Documents;
      10. using System.Windows.Input;
      11. using System.Windows.Media;
      12. using System.Windows.Media.Imaging;
      13. using System.Windows.Navigation;
      14. using System.Windows.Shapes;
      15. using System.Windows.Threading;
      16. namespace Binäruhr
      17. {
      18. public partial class MainWindow : Window
      19. {
      20. DispatcherTimer t;
      21. Color colorOn = Colors.Red;
      22. Color colorOff = Colors.LightGray;
      23. public MainWindow()
      24. {
      25. InitializeComponent();
      26. t = new DispatcherTimer();
      27. t.Interval = new TimeSpan(0, 0, 0, 0, 100);
      28. t.Tick += t_Tick;
      29. t.Start();
      30. initField();
      31. }
      32. public void initField()
      33. {
      34. for(int x = 0; x < 3; x++)
      35. {
      36. String temp = "";
      37. if (x == 0)
      38. temp = "s";
      39. if (x == 1)
      40. temp = "m";
      41. if (x == 2)
      42. temp = "h";
      43. for(int y = 0; y < 32; y++)
      44. {
      45. if(temp != "h")
      46. {
      47. setBit(temp + (y+1).ToString(), false);
      48. }
      49. else
      50. {
      51. if(y < 30)
      52. setBit(temp + (y+1).ToString(), false);
      53. }
      54. }
      55. }
      56. }
      57. public void setBit(String bit, bool status)
      58. {
      59. char c = bit[0];
      60. String temp = bit.Substring(1, bit.Length - 1);
      61. int i = Int32.Parse(temp);
      62. SolidColorBrush brusch = new SolidColorBrush(status == true ? colorOn : colorOff);
      63. switch(c)
      64. {
      65. case 's':
      66. {
      67. switch(i)
      68. {
      69. case 1:
      70. {
      71. s1.Background = brusch;
      72. break;
      73. }
      74. case 2:
      75. {
      76. s2.Background = brusch;
      77. break;
      78. }
      79. case 4:
      80. {
      81. s4.Background = brusch;
      82. break;
      83. }
      84. case 8:
      85. {
      86. s8.Background = brusch;
      87. break;
      88. }
      89. case 16:
      90. {
      91. s16.Background = brusch;
      92. break;
      93. }
      94. case 32:
      95. {
      96. s32.Background = brusch;
      97. break;
      98. }
      99. }
      100. break;
      101. }
      102. case 'm':
      103. {
      104. switch (i)
      105. {
      106. case 1:
      107. {
      108. m1.Background = brusch;
      109. break;
      110. }
      111. case 2:
      112. {
      113. m2.Background = brusch;
      114. break;
      115. }
      116. case 4:
      117. {
      118. m4.Background = brusch;
      119. break;
      120. }
      121. case 8:
      122. {
      123. m8.Background = brusch;
      124. break;
      125. }
      126. case 16:
      127. {
      128. m16.Background = brusch;
      129. break;
      130. }
      131. case 32:
      132. {
      133. m32.Background = brusch;
      134. break;
      135. }
      136. }
      137. break;
      138. }
      139. case 'h':
      140. {
      141. switch (i)
      142. {
      143. case 1:
      144. {
      145. h1.Background = brusch;
      146. break;
      147. }
      148. case 2:
      149. {
      150. h2.Background = brusch;
      151. break;
      152. }
      153. case 4:
      154. {
      155. h4.Background = brusch;
      156. break;
      157. }
      158. case 8:
      159. {
      160. h8.Background = brusch;
      161. break;
      162. }
      163. case 16:
      164. {
      165. h16.Background = brusch;
      166. break;
      167. }
      168. }
      169. break;
      170. }
      171. }
      172. }
      173. public void setTime()
      174. {
      175. int temp2 = DateTime.Now.Second;
      176. String tempS = Convert.ToString(DateTime.Now.Second, 2);
      177. String tempM = Convert.ToString(DateTime.Now.Minute, 2);
      178. String tempH = Convert.ToString(DateTime.Now.Hour, 2);
      179. String s = "";
      180. String m = "";
      181. String h = "";
      182. int x = 0;
      183. for (int i = (tempS.Length - 1); i >= 0; i--)
      184. {
      185. s += tempS[i].ToString();
      186. }
      187. x = 6 - (int)s.Length;
      188. for (int i = 0; i < x; i++)
      189. {
      190. s += "0";
      191. }
      192. for(int i= (tempM.Length -1); i >= 0; i--)
      193. {
      194. m += tempM[i].ToString();
      195. }
      196. x = 6 - (int)m.Length;
      197. for (int i = 0; i < x; i++)
      198. {
      199. m += "0";
      200. }
      201. for (int i = (tempH.Length - 1); i >= 0; i--)
      202. {
      203. h += tempH[i].ToString();
      204. }
      205. x = 5 - h.Length;
      206. for (int i = 0; i < x; i++)
      207. {
      208. h += "0";
      209. }
      210. setBit("s1", s[0] == '1' ? true : false);
      211. setBit("s2", s[1] == '1' ? true : false);
      212. setBit("s4", s[2] == '1' ? true : false);
      213. setBit("s8", s[3] == '1' ? true : false);
      214. setBit("s16", s[4] == '1' ? true : false);
      215. setBit("s32", s[5] == '1' ? true : false);
      216. setBit("m1", m[0] == '1' ? true : false);
      217. setBit("m2", m[1] == '1' ? true : false);
      218. setBit("m4", m[2] == '1' ? true : false);
      219. setBit("m8", m[3] == '1' ? true : false);
      220. setBit("m16", m[4] == '1' ? true : false);
      221. setBit("m32", m[5] == '1' ? true : false);
      222. setBit("h1", h[0] == '1' ? true : false);
      223. setBit("h2", h[1] == '1' ? true : false);
      224. setBit("h4", h[2] == '1' ? true : false);
      225. setBit("h8", h[3] == '1' ? true : false);
      226. setBit("h16", h[4] == '1' ? true : false);
      227. }
      228. void t_Tick(object sender, EventArgs e)
      229. {
      230. setTime();
      231. }
      232. }
      233. }



      Und so wie sich's gehört, ein Bildschirmschuss :D :





      Mit freundlichen Grüßen
      nxtman
      Dateien
      • BinaerUhrMVVM.rar

        (120,13 kB, 164 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nxtman“ () aus folgendem Grund: "Finalen" Code eingefügt

      Moin,

      sieht so aus, als hättest Du die Controls aus der Toolbox auf die Form gezogen, das geht in WPF nicht. Da schreibt man den Code selbst.
      Außerdem vermisse ich das MVVM, also ein gescheites ViewModel etc., dass Daten und GUI trennt. Stattdessen nutzt Du halt hier den Codebehind, das würde ich anders machen.

      @nafets Lass mich. :P

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      @nafets
      Wo steht das denn eigentlich, dass WPF-Programme immer mit dem MVVM Pattern erstellt werden müssen?
      Soweit ich weiß existierte das MVVM Pattern noch nicht einmal wie WPF erstmals erschienen ist.

      Nicht falsch verstehen. Das MVVM Pattern ist toll. Jedoch nicht das Allereinzigste in WPF.

      @Trade
      Auch hier nicht falsch verstehen. Ich kann sehr wohl Controls auf eine WPF Form ziehen.

      Auch wenn es vielleicht (mittlerweile) nicht mehr zeitgemäß ist, das Programm so zu schreiben wie der TE es gemacht hat funktioniert es ja (habs aber nicht getestet).

      Eventuell könnte jemand mal eine Binäruhr mit MVVM Pattern erstellen und hier veröffentlichen. Interessieren würde mich es auf jeden Fall wie das aufgebaut wäre :)

      lg
      ScheduleLib 0.0.1.0
      Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
      Hier kein MVVM zu nutzen macht die Sache bloß schwerer. Diese riesigen Switch-Blöcke könnten einfach verschwinden, wenn man statt einzelnen Steuerelementen Listen o.ä. verwendet, die an das UI gebunden sind.
      Für das UI sollten die "Lampen" nicht mehr als 3 boolean-Listen (geht auch eine?) sein, der Codebehind sollte dann sehr viel einfacher ausfallen, weil statt vielen Abfragen einfache Arithmetik zum setzen der Lampen verwendet werden kann.

      Artentus schrieb:

      Mit Triggern natürlich.
      Wos SourceCodemäßig anfängt interessant zu werden.
      Ich zB. würde zu 'nem Converter greifen - müsste man glatt mal nebeneinander stellen, die Ansätze.
      Prinzipiell könnte man das Datenmodell auf 3 ObservableCollection(Of Boolean) reduzieren, je eine für Stunde, Minute, Sekunde.
      Ich würde auch nen Converter nehmen. Aber was ich mich erstmal frage, ist, ob ein ViewModel bei einer Binäruhr (Ich habs mir jetzt nicht so genau angeguckt, aber es sieht sehr nach View-only aus) sinnvoll wäre. Ich würde (und lasse mich auch gerne eines besseres belehren), dann auch im View bleiben. Das heißt: 1. Lösungsansatz: Ein eigenes Control schreiben. Usercontrol hinzufügen und im UserControl INotifyPropertyChanged implementieren. Dann kann man dem UserControl einen Namen geben (x:Name) und dann vom View zu den Eigenschaften des UserControls binden (also quasi das View als "ViewModel" verwenden, nur halt das es der View ist und kein ViewModel):

      XML-Quellcode

      1. {Binding ElementName=usercontrol,Path=Irgendeine Eigenschaft}


      2. Lösungsansatz wäre dann das gleiche nur in dem Window. Also das dann in der Codebehind-Datei des Views Eigenschaften erstellt werden, an die dann mit {Binding ElementName=window,Path=MeineEigenschaft} zugegriffen werden kann.
      Mfg
      Vincent

      ich konnts halt nicht lassen :-\
      MainModel

      VB.NET-Quellcode

      1. Imports System.ComponentModel
      2. Imports System.Collections.ObjectModel
      3. Imports System.Windows.Threading
      4. Public Class MainModel : Inherits MainModelBase(Of MainModel)
      5. Private WithEvents _Timer As New DispatcherTimer With {.Interval = TimeSpan.FromSeconds(0.3)}
      6. Public Property ColHeads As String() = "Hour Min Sec".Split
      7. Public Property RowHeads As String() = "1 2 4 8 16 32".Split
      8. Public Property Seconds As New ObservableCollection(Of Boolean) From {False, False, False, False, False, False}
      9. Public Property Minutes As New ObservableCollection(Of Boolean) From {False, False, False, False, False, False}
      10. Public Property Hours As New ObservableCollection(Of Boolean) From {False, False, False, False, False}
      11. Private _Time As Date
      12. Public Property Time As Date
      13. Get
      14. Return _Time
      15. End Get
      16. Private Set(ByVal value As Date)
      17. value -= TimeSpan.FromMilliseconds(value.Millisecond)
      18. If ChangePropIfDifferent(value, _Time, "Time") Then UpdateBinary()
      19. End Set
      20. End Property
      21. Public Sub New()
      22. If IsProvisional Then Return
      23. _Timer.Start()
      24. AddHandler _Timer.Tick, Sub(s, e) Time = Date.Now
      25. End Sub
      26. Private Function ToBinary(ByVal cols As Integer, ByVal value As Integer) As List(Of Boolean)
      27. Dim format = String.Concat("{0:", New String("0"c, cols), "}")
      28. Dim s = String.Format(format, Integer.Parse(Convert.ToString(value, 2)))
      29. Return s.Select(Function(c) c = "1"c).Reverse.ToList
      30. End Function
      31. Private Sub UpdateBinary()
      32. For Each itm In {Seconds, Minutes, Hours}.Zip({_Time.Second, _Time.Minute, _Time.Hour}, Function(lst, value) New With {lst, value})
      33. Dim list = itm.lst
      34. Dim bValues = ToBinary(list.Count, itm.value)
      35. For i = 0 To list.Count - 1
      36. If list(i) <> bValues(i) Then list(i) = bValues(i)
      37. Next
      38. Next
      39. End Sub
      40. End Class

      Xaml

      XML-Quellcode

      1. <Window x:Class="MainWindow"
      2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      4. xmlns:my="clr-namespace:BinaryClock"
      5. xmlns:sys="clr-namespace:System;assembly=mscorlib"
      6. xmlns:hlp="clr-namespace:System.Windows.Controls;assembly=WpfHelpers"
      7. Title="{Binding Path=Time, StringFormat={} \{0:T\}}"
      8. DataContext="{Binding Source={StaticResource Mainmodel}}" SizeToContent="WidthAndHeight" WindowStyle="ToolWindow">
      9. <FrameworkElement.Resources>
      10. <hlp:BoolConverter x:Key="Colors">
      11. <SolidColorBrush Color="Red" />
      12. <SolidColorBrush Color="Silver" />
      13. </hlp:BoolConverter>
      14. <DataTemplate x:Key="BitItem" DataType="{x:Type sys:Boolean}">
      15. <Grid HorizontalAlignment="Center">
      16. <Grid.RowDefinitions>
      17. <RowDefinition SharedSizeGroup="BitHeigth" Height="auto" />
      18. </Grid.RowDefinitions>
      19. <Grid.ColumnDefinitions>
      20. <ColumnDefinition SharedSizeGroup="BitWidth" Width="auto" />
      21. </Grid.ColumnDefinitions>
      22. <Ellipse Fill="{Binding Converter={StaticResource Colors}}" Width="16" Height="16" />
      23. </Grid>
      24. </DataTemplate>
      25. </FrameworkElement.Resources>
      26. <hlp:GridEx RowDefs="auto," ColumnDefs="auto,,," Grid.IsSharedSizeScope="True" Margin="10">
      27. <ItemsControl hlp:GridEx.Range="a2" ItemsSource="{Binding Path=RowHeads}">
      28. <ItemsControl.ItemTemplate>
      29. <DataTemplate DataType="{x:Type sys:Int32}">
      30. <Grid>
      31. <Grid.RowDefinitions>
      32. <RowDefinition SharedSizeGroup="BitHeigth" />
      33. </Grid.RowDefinitions>
      34. <TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="2" />
      35. </Grid>
      36. </DataTemplate>
      37. </ItemsControl.ItemTemplate>
      38. </ItemsControl>
      39. <ItemsControl hlp:GridEx.Range="b1 c" ItemsSource="{Binding Path=ColHeads}">
      40. <ItemsControl.ItemsPanel>
      41. <ItemsPanelTemplate>
      42. <UniformGrid Columns="3" />
      43. </ItemsPanelTemplate>
      44. </ItemsControl.ItemsPanel>
      45. <ItemsControl.ItemTemplate>
      46. <DataTemplate DataType="{x:Type sys:Int32}">
      47. <TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="2" />
      48. </DataTemplate>
      49. </ItemsControl.ItemTemplate>
      50. </ItemsControl>
      51. <ItemsControl hlp:GridEx.Range="b2" ItemsSource="{Binding Path=Hours}" ItemTemplate="{StaticResource BitItem}" />
      52. <ItemsControl hlp:GridEx.Range="c2" ItemsSource="{Binding Path=Minutes}" ItemTemplate="{StaticResource BitItem}" />
      53. <ItemsControl hlp:GridEx.Range="d2" ItemsSource="{Binding Path=Seconds}" ItemTemplate="{StaticResource BitItem}" />
      54. </hlp:GridEx>
      55. </Window>



      Bisserl irritierend anne Solution werden meine enthaltenen Helpers-Projekte sein - von denen brauch ich halt das GridEx, den BoolConverter und die MainmodelBase.
      Dateien
      • BinaryClock.zip

        (90,9 kB, 141 mal heruntergeladen, zuletzt: )
      Und hier das DataTemplate, wenn man mit Trigger arbeiten will:
      Spoiler anzeigen

      XML-Quellcode

      1. <DataTemplate x:Key="BitItem2" DataType="{x:Type sys:Boolean}">
      2. <Grid HorizontalAlignment="Center">
      3. <Grid.RowDefinitions>
      4. <RowDefinition SharedSizeGroup="BitHeigth" Height="auto" />
      5. </Grid.RowDefinitions>
      6. <Grid.ColumnDefinitions>
      7. <ColumnDefinition SharedSizeGroup="BitWidth" Width="auto" />
      8. </Grid.ColumnDefinitions>
      9. <Ellipse x:Name="Circle" Fill="Silver" Width="16" Height="16" />
      10. </Grid>
      11. <DataTemplate.Triggers>
      12. <DataTrigger Binding="{Binding}" Value="True">
      13. <Setter TargetName="Circle" Property="Fill" Value="Red"/>
      14. </DataTrigger>
      15. </DataTemplate.Triggers>
      16. </DataTemplate>
      Es kommt tatsächlich ziemlich genau aufs selbe raus, oder ist sogar etwas vorteilhaft, da man auf mein BoolConverter verzichten kann.
      So, nach "kurzem" eingewöhnen und ein paar Tutorials hab ich das System gecheckt.

      Ich arbeite, um das bool in Farbe umzuwandeln, mit einem Converter. Das habe ich aus meinem WPF-Buch abgeguckt :whistling:
      Funktionsweise um die Zeit umzuwandeln ist die selbe wie vorher.

      Guckts euch einfach an:

      Converter.cs

      C#-Quellcode

      1. using System;
      2. using System.Globalization;
      3. using System.Windows.Data;
      4. using System.Windows.Media;
      5. namespace BinaerUhrMVVM.Converters
      6. {
      7. [ValueConversion(typeof(bool),typeof(Brush))]
      8. public class Converter : IValueConverter
      9. {
      10. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      11. {
      12. if ((bool)value)
      13. return Brushes.Red;
      14. return Brushes.LightGray;
      15. }
      16. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      17. {
      18. throw new NotImplementedException();
      19. }
      20. }
      21. }



      ZeitSpeicher.cs

      C#-Quellcode

      1. using System;
      2. using System.ComponentModel;
      3. using System.Collections.ObjectModel;
      4. namespace BinaerUhrMVVM
      5. {
      6. public class ZeitSpeicher : INotifyPropertyChanged
      7. {
      8. public ZeitSpeicher()
      9. {
      10. _listH = new ObservableCollection<bool>();
      11. _listM = new ObservableCollection<bool>();
      12. _listS = new ObservableCollection<bool>();
      13. }
      14. private ObservableCollection<bool> _listH;
      15. private ObservableCollection<bool> _listM;
      16. private ObservableCollection<bool> _listS;
      17. public ObservableCollection<bool> listH
      18. {
      19. get { return _listH; }
      20. set
      21. {
      22. _listH = value;
      23. OnPropertyChanged("listH");
      24. }
      25. }
      26. public ObservableCollection<bool> listM
      27. {
      28. get { return _listM; }
      29. set
      30. {
      31. _listM = value;
      32. OnPropertyChanged("listM");
      33. }
      34. }
      35. public ObservableCollection<bool> listS
      36. {
      37. get { return _listS; }
      38. set
      39. {
      40. _listS = value;
      41. OnPropertyChanged("listS");
      42. }
      43. }
      44. public void init()
      45. {
      46. _listH.Clear();
      47. setBit('h', 1, false);
      48. setBit('h', 2, false);
      49. setBit('h', 4, false);
      50. setBit('h', 8, false);
      51. setBit('h', 16, false);
      52. _listM.Clear();
      53. setBit('m', 1, false);
      54. setBit('m', 2, false);
      55. setBit('m', 4, false);
      56. setBit('m', 8, false);
      57. setBit('m', 16, false);
      58. setBit('m', 32, false);
      59. _listS.Clear();
      60. setBit('s', 1, false);
      61. setBit('s', 2, false);
      62. setBit('s', 4, false);
      63. setBit('s', 8, false);
      64. setBit('s', 16, false);
      65. setBit('s', 32, false);
      66. }
      67. public void setTime()
      68. {
      69. String tempS = Convert.ToString(DateTime.Now.Second, 2);
      70. String tempM = Convert.ToString(DateTime.Now.Minute, 2);
      71. String tempH = Convert.ToString(DateTime.Now.Hour, 2);
      72. String s = "";
      73. String m = "";
      74. String h = "";
      75. int x = 0;
      76. for (int i = (tempS.Length - 1); i >= 0; i--)
      77. s += tempS[i].ToString();
      78. x = 6 - (int)s.Length;
      79. for (int i = 0; i < x; i++)
      80. s += "0";
      81. for (int i = (tempM.Length - 1); i >= 0; i--)
      82. m += tempM[i].ToString();
      83. x = 6 - (int)m.Length;
      84. for (int i = 0; i < x; i++)
      85. m += "0";
      86. for (int i = (tempH.Length - 1); i >= 0; i--)
      87. h += tempH[i].ToString();
      88. x = 5 - h.Length;
      89. for (int i = 0; i < x; i++)
      90. h += "0";
      91. for (int i = 0; i < 6; i++)
      92. {
      93. changeBit('s', i, s[i] == '1' ? true : false);
      94. changeBit('m', i, m[i] == '1' ? true : false);
      95. if(i < 5)
      96. changeBit('h', i, h[i] == '1' ? true : false);
      97. }
      98. }
      99. public void setBit(char liste, int bit, bool value)
      100. {
      101. if(char.IsLetter(liste) && !char.IsWhiteSpace(liste))
      102. {
      103. switch(liste)
      104. {
      105. case 'h':
      106. {
      107. listH.Add(value);
      108. break;
      109. }
      110. case 'm':
      111. {
      112. listM.Add(value);
      113. break;
      114. }
      115. case 's':
      116. {
      117. listS.Add(value);
      118. break;
      119. }
      120. }
      121. }
      122. }
      123. public void changeBit(char liste, int bit, bool value)
      124. {
      125. if (char.IsLetter(liste) && !char.IsWhiteSpace(liste))
      126. {
      127. switch (liste)
      128. {
      129. case 'h':
      130. {
      131. listH[bit] = value;
      132. OnPropertyChanged("listH");
      133. break;
      134. }
      135. case 'm':
      136. {
      137. listM[bit] = value;
      138. OnPropertyChanged("listM");
      139. break;
      140. }
      141. case 's':
      142. {
      143. listS[bit] = value;
      144. OnPropertyChanged("listS");
      145. break;
      146. }
      147. }
      148. }
      149. }
      150. #region INotifyPropertyChanged Members
      151. public event PropertyChangedEventHandler PropertyChanged;
      152. private void OnPropertyChanged(string propertyName)
      153. {
      154. PropertyChangedEventHandler handler = PropertyChanged;
      155. if (handler != null)
      156. {
      157. handler(this, new PropertyChangedEventArgs(propertyName));
      158. }
      159. }
      160. #endregion
      161. }
      162. }




      UhrModel.cs

      C#-Quellcode

      1. using System;
      2. using System.Windows;
      3. using System.Windows.Threading;
      4. namespace BinaerUhrMVVM.ViewModel
      5. {
      6. internal class UhrModel
      7. {
      8. public UhrModel()
      9. {
      10. _time = new ZeitSpeicher();
      11. _time.init();
      12. timer = new DispatcherTimer();
      13. timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
      14. timer.Tick += timer_Tick;
      15. timer.Start();
      16. }
      17. void timer_Tick(object sender, EventArgs e)
      18. {
      19. _time.setTime();
      20. }
      21. private DispatcherTimer timer;
      22. private ZeitSpeicher _time;
      23. public ZeitSpeicher time
      24. {
      25. get { return _time; }
      26. }
      27. }
      28. }



      Uhr.xaml (Haupt-Form)

      XML-Quellcode

      1. <Window x:Class="BinaerUhrMVVM.MainWindow"
      2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      4. xmlns:vm="clr-namespace:BinaerUhrMVVM.ViewModel"
      5. xmlns:cnv="clr-namespace:BinaerUhrMVVM.Converters"
      6. Title="Binär-Uhr" Height="235" Width="166" KeyboardNavigation.TabNavigation="None" MinWidth="180" MinHeight="250" WindowStyle="ToolWindow" ResizeMode="NoResize" >
      7. <Window.Resources>
      8. <vm:UhrModel x:Key="uhr" />
      9. <cnv:Converter x:Key="boolToBrushConverter" />
      10. </Window.Resources>
      11. <Grid DataContext="{StaticResource uhr}" >
      12. <Grid.ColumnDefinitions>
      13. <ColumnDefinition Width="*" />
      14. <ColumnDefinition Width="auto" />
      15. <ColumnDefinition Width="auto" />
      16. <ColumnDefinition Width="auto" />
      17. <ColumnDefinition Width="*" />
      18. </Grid.ColumnDefinitions>
      19. <Grid.RowDefinitions>
      20. <RowDefinition Height="10" />
      21. <RowDefinition Height="30" />
      22. <RowDefinition Height="*" />
      23. </Grid.RowDefinitions>
      24. <TextBlock Text="h:" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
      25. <TextBlock Text="m:" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
      26. <TextBlock Text="s:" Grid.Column="3" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
      27. <ListBox Grid.Column="0" Grid.Row="3" HorizontalAlignment="Right" VerticalAlignment="Top" BorderBrush="{x:Null}" Background="{x:Null}" Focusable="False" >
      28. <Label Content="1" Height="25" Width="25" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" />
      29. <Label Content="2" Height="25" Width="25" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" />
      30. <Label Content="4" Height="25" Width="25" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" />
      31. <Label Content="8" Height="25" Width="25" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" />
      32. <Label Content="16" Height="25" Width="25" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" />
      33. <Label Content="32" Height="25" Width="25" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" />
      34. </ListBox>
      35. <ListBox ItemsSource="{Binding time.listH, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="3" VerticalAlignment="Top" Background="{x:Null}" BorderBrush="{x:Null}" Focusable="False" >
      36. <ListBox.ItemTemplate>
      37. <DataTemplate>
      38. <Border Height="25" Width="25" Padding="4">
      39. <Border Grid.Column="1" Background="{Binding BindsDirectlyToSource=True, Converter={StaticResource boolToBrushConverter}, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
      40. </Border>
      41. </DataTemplate>
      42. </ListBox.ItemTemplate>
      43. </ListBox>
      44. <ListBox ItemsSource="{Binding time.listM, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="3" VerticalAlignment="Top" Background="{x:Null}" BorderBrush="{x:Null}" Focusable="False" >
      45. <ListBox.ItemTemplate>
      46. <DataTemplate>
      47. <Border Height="25" Width="25" Padding="4">
      48. <Border Grid.Column="1" Background="{Binding BindsDirectlyToSource=True, Converter={StaticResource boolToBrushConverter}, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
      49. </Border>
      50. </DataTemplate>
      51. </ListBox.ItemTemplate>
      52. </ListBox>
      53. <ListBox ItemsSource="{Binding time.listS, UpdateSourceTrigger=PropertyChanged}" Grid.Column="3" Grid.Row="3" VerticalAlignment="Top" Background="{x:Null}" BorderBrush="{x:Null}" Focusable="False" >
      54. <ListBox.ItemTemplate>
      55. <DataTemplate>
      56. <Border Height="25" Width="25" Padding="4">
      57. <Border Grid.Column="1" Background="{Binding BindsDirectlyToSource=True, Converter={StaticResource boolToBrushConverter}, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
      58. </Border>
      59. </DataTemplate>
      60. </ListBox.ItemTemplate>
      61. </ListBox>
      62. <Border Grid.RowSpan="10" Grid.ColumnSpan="10" Background="#02FFFFFF" />
      63. </Grid>
      64. </Window>




      Bildschirmschuss:




      Das fenster hat keinen Pups Codebehind :D

      Das Projekt ist im Anhang.


      Lasst es Kritik hageln!

      Mfg nxtman
      Dateien
      • BinaerUhrMVVM.rar

        (66,59 kB, 116 mal heruntergeladen, zuletzt: )
      ich für mein Teil bin schwer beeindruckt.
      Du hast wirklich innerhalb von 3 Tagen den MVVM-Pattern von 0 auf 100 gecheckt!
      :thumbsup:

      Kannst noch ein paar Redundanzen abbauen, weil im Xaml hast du ja zB die ItemTemplates 3 mal gecodet, die sollte man (als Resource) nur einmal coden, und dann den Listboxen als StaticResource mitgeben.
      Ah - und UpdateSourceTrigger sind in keinem Fall erforderlich. Es gibt ja keine User-Eingabe, die in die DataSource rückzutransferieren wäre, also die Source soll nie geupdated wern.

      Einigen Aufwand hast du getrieben, um Listbox-Funktionalität zu disablen. Probier stattdessen auch mal die Basisklasse von Listbox: ItemsControl - die hat diese Funktionalität erst garnet :P

      Im Zeitspeicher dein Code ist sehr umständlich.
      Zum einen kann man auch in c# sehr elegant Auflistungen initialisieren, zum andern - also dieses Tripel von setTime, setBit, changeBit - also das geht wirklich einfacher.

      Guckma, bei mir ist das alles nur eine Methode (hier die inzwischen wesentlich verbesserte Version):

      VB.NET-Quellcode

      1. Private Sub UpdateBinary()
      2. For Each itm In {Seconds, Minutes, Hours}.Zip({_Time.Second, _Time.Minute, _Time.Hour}, Function(lst, value) New With {lst, value})
      3. With itm
      4. For i = 0 To .lst.Count - 1
      5. Dim b = (.value And (1 << i)) > 0
      6. If .lst(i) <> b Then .lst(i) = b
      7. Next
      8. End With
      9. Next
      10. End Sub
      Seconds, Minutes, Hours sind die ObservableCollections, und _Time ist halt die aktuelle Zeit - ist bei mir ja eine KlassenVariable, an die letztlich auch gebunden wird.
      Die Zuweisung der Bits basiert nun auf bitweisen Operatoren <<, And, wie sich das für eine Binär-Uhr ja wohl gehört ;)

      Edit:
      Ach, und was hier noch ganz unnötig ist: INotifyPropertyChanged. Normal ist solch nötig, aber hier die ObservableCollections übernehmen das mit - s. post#10

      ich kanns malwieder nicht lassen

      C#-Quellcode

      1. using System;
      2. using System.ComponentModel;
      3. using System.Collections.ObjectModel;
      4. using System.Linq;
      5. namespace BinaerUhrMVVM {
      6. public class ZeitSpeicher {
      7. public ObservableCollection<bool> listH { get; private set; }
      8. public ObservableCollection<bool> listM { get; private set; }
      9. public ObservableCollection<bool> listS { get; private set; }
      10. private ObservableCollection<bool>[] _TimeLists;
      11. public ZeitSpeicher() {
      12. listH = new ObservableCollection<bool>(new bool[5]);
      13. listM = new ObservableCollection<bool>(new bool[6]);
      14. listS = new ObservableCollection<bool>(new bool[6]);
      15. _TimeLists = new ObservableCollection<bool>[] { listS, listM, listH };
      16. }
      17. public void setTime() {
      18. DateTime _Time = DateTime.Now;
      19. var items = _TimeLists.Zip(new int[] { _Time.Second, _Time.Minute, _Time.Hour }, (lst, value) => new { lst, value });
      20. foreach (var itm in items) {
      21. for (var i = 0; i <= itm.lst.Count - 1; i++) {
      22. var b = (itm.value & (1 << i)) > 0;
      23. if (itm.lst[i] != b) itm.lst[i] = b;
      24. }
      25. }
      26. }
      27. }
      28. }

      Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „ErfinderDesRades“ ()

      @nxtman aus welchem Buch hast du das WPF? und könntest du vllt ein paar der von dir geschauten Videos/angeschauten Webseiten, die du als Tutorial genutzt hast hier posten oder mir per PN schicken?
      @nxtman: echt?
      Dein Code ist aber doch viel besser, als was der da im Video zurechtfrickelt.
      1. Du setzst den DataContext im Xaml, nicht im Codebehind.
        Das eröffnet dir MVVM: "Binding-Picking" im Xaml-Editor , was dem Vortragenden nicht zur Verfügung steht, und was er auch ühaupt nicht zu kennen scheint.
      2. Du hast nicht sone überverkomplizierte Architektur mit Customer und CustomerViewmodel, was doch nix anneres macht, als den Customer durchzureichen, sondern du hast nur gecodet, was auch gebraucht wird.
      Für mich ist das son typisches Video, wo man dem Genie auf der Alm eine halbe Stunde zugucken muss, wie er Text in den Editor tippt, und man fragt sich hinterher: "Ja, warum stellt er das nicht einfach zum Download? - ich werd hier doch nicht anfangen, Code vom Bildschirm abzutippen!"
      Durch das video habe ich die grobe Struktur von MVVM kapiert. Dass der da was im Code-Behind rumfuckelt hat mich nicht gestört, weil ich wusste dass man den data-Context auch in XAML setzen kann.

      ErfinderDesRades schrieb:

      Für mich ist das son typisches Video, wo man dem Genie auf der Alm eine halbe Stunde zugucken muss, wie er Text in den Editor tippt, und man fragt sich hinterher: "Ja, warum stellt er das nicht einfach zum Download? - ich werd hier doch nicht anfangen, Code vom Bildschirm abzutippen!"


      Da gebe ich dir recht ^^ diese Kategorie Videos mag ich auch nicht. Ich habs mir halt auf meinem Handy, abends im Bett, angeguckt von daher war mir das egal dass der nicht den Code bereitstellt.

      Ich werde nacher auch mal meinen Code verbesserrn, mal sehen ob ich das auch so schick hin bekomme wie du :D
      Was ist das eigentlich für ein Zip Befehl, den du da verwendest?