Oder setzt dort mal
m_progressbar.Value = m_progressbar.Maximum;
Schon komisch, kannst du mal Testhalber ein Invalidate an der Progressbar aufrufen sobald du den Value change durchführst. Sollte zwar implizit von der PB gemacht werden aber probiere es trotzdem mal.
Hallo tööö,
du redest hier immer von Prozent, wie ist denn dein Minimum und dein Maximum deiner Progressbar? Hast du mal geschaut das auch das Maximum und das Value gleich sind (bei 100%)?
Das Zauberwort heißt Event, daher definiere ein Event das du feuerst sobald ein Thread seine Arbeit beendet hat. Dann musst du es nur noch gescheit auswerten.
edit: Ergänzung, die Methode RsUpload(..) ist ja deine dem Thread zugeteilte Methode, daher am Ende der Methode, einfach das eigens definierte Event feuern, denn ist die Methode beendet, wird ja auch der Thread beendet.
Nein nicht wirklich.
Leg dir eine Form an, und dann fügst du einen EventHandler hinzu den du an das MouseDown event bindest.
form.MouseDown += new System.Windows.Forms.MouseEventHandler(MouseDownMethod);
void MouseDownMethod(object sender, System.Windows.Forms.MouseEventArgs e)
{
throw new NotImplementedException();
}
Wenn du nun in der Form die Mouse drückst, und den debugger anhast und einen BreakPoint in der MouseDownMethod hast, dann landest du darin.
Verstanden?
Du kannst dir ja eine eigene Rectangle Klasse erstellen. Die enthält halt ein paar Daten wie Höhe, Länge und obere linke Ecke. Dann noch ein flag ob sie gerade dedrückt ist oder nicht.
Dann machst du dir einfach eine Liste all deiner Rectangle Objecte und bei einem MouseDown Event suchst du einfach alle Rectangles durch die diesen Punkt enthalten und setzt dort dann das Flag. Wenn nun ein MouseMove event kommt, dann einfach alle Rectangles die das Flag gesetzt haben um den Diff(x,y) verschieben. Wenn MouseUp kommt dann alle Flags zurück setzen.
Schau dir mal MouseUp MouseDown und MouseMove an einem Control an.
MSDN
Um man es unterbinden kann weiß ich nicht genau, auf jeden fall kannst du dir die Position vor dem aktuallisieren merken, und danach dann dort hin scrollen.
DataGridView.FirstDisplayedScrollingRowIndex = 20;
Hallo zerberos,
erstens warum legst du vorher eine leere Textbox an um sie dann wieder zu überschreiben.
Dann zu deiner Syntax, denn die versteh ich nicht richtig. (0) am ende der Find Methode ist doch syntaktisch falsch!?
Wenn die Control Collection eine Textbox mit dem Key "box" enthält dann bekommst du die so zurück:
TextBox txt = this.Controls.Find("box", true)[0] as TextBox;
[edit]: Das ist ne Collection, das habe ich übersehen...
Ja das ist logisch das er nicht drauf zugreifen kann. Wie BerndFfm bereits erwähnte solltest du dir den Link den er dir gegeben hat mal anschauen.
Grundsätzlich darfst du auf GUI controls nur in dem Thread zugreifen der das Control erzeugt hat. Da du einen neuen Thread erzeugst der deine Datenbank ausliest, musst du deine Controls per Delegate und Invoke aus dem erzeugten Thread updaten.
Hallo w1z4rd2003,
hast du mal zur Laufzeit per Refelction und Debugger in die EventList der ListBox geschaut ob da auch wirklich deine Mehtode drin steht die gefeuert werden soll?
Außerdem sieht das bisschen komisch aus (zumindest für micht) das du zum einen eine Reference eines ListBox objectes übergibts, aber zugleich auch diese Reference returnst. Ich weiß das du damit dir in dem Beispiel einen Schritt sparst, aber komisch sieht es trotzdem aus...
Das wäre eine Option, m.E. auch die letzte. Ich habe es trotzdem so gelöst wie oben beschrieben, daher die Progressbar.Maxmium auf 3 gesetzt und nach jedem Schritt wird das Value inkrementiert. Das funktioniert auch, da dort ja ClearCase kurze zeit lang nicht aktiv ist. Von daher ist das so akzeptabel, da der User ja nur mitbekommen soll das sich was tut 😃
Mir ist zumindest nichts bekannt, deswegen frage ich ja hier. Na gut dann werde ich es wohl so machen müssen das ich den Progressbar auf 3 Stelle. Auschecken, manipulieren, und einchecken. Nur weil das aus und ein checken deutlich länger dauert als der manipulation, wollt ich einfach einen animierten Progressbar machen.
Wenn einer noch eine Idee hat, dann bitte posten.
Mit dem dreckstool stimme ich dir zu. Also meinst du auch das es einfach an der Performance liegt, und nicht daran das die CAL via COM interagiert und daher der GUI Thread nicht richtig bearbeitet wird? Weil im Studio zum Beispiel wird der progressbar auch aktuallisiert wenn man mehrere Files auscheckt.
Hallo zusammen ich habe folgendes Problem. Ich muss eine Datei manipulieren die unter SourceControl (Rational ClearCase) steht. Dazu gibt es eine Library CAL mit Hilfe dieser es relativ einfach ist. Man kann durch die Library das ClearTool wie in der Comandozeile bedienen. Daher ist das ein und auschecken kein Problem.
Jetzt zum eigentlichen Problem.
Während dieses Vorganges schalte ich ein Progressbar auf Style = ProgressBarStyle.Marquee! Danach starte ich eine Thread der das ein und auschecken übernimmt. Kleines Beispiel.
private void StartSavingProgress()
{
for (int i = 0; i < 100000; i++)
{
for (int j = 0; j < 100000; j++)
{
//nothing
}
}
}
public void Main()
{
this.m_thread = new Thread(new ThreadStart(this.StartSavingProgress));
this.m_progressBar.MarqueeAnimationSpeed = 20;
this.m_progressBar.Style = ProgressBarStyle.Marquee;
this.m_thread.Start();
}
Dort funkioniert das alles bestens, daher auch wenn ich mich im Thread befinde wird die Progressbar ordentlich animiert.
Nun mein Problem.
private void StartSavingProgress()
{
CC.ClearCaseHelper.CheckOut("filepath");
...
CC.ClearCaseHelper.CheckIn("filepath");
}
Jetzt wird die Progressbar jedoch nicht mehr korrekt animiert, sie hängt und wird nur sehr unregelmäßig geupdatet. Ich versteh das ganze nicht richtig, da ich doch den CheckOut/CheckIn Prozess in einen eigenen Thread ausgelagert habe.
Weiß einer von euch Rat?
Jetzt versteh ich gar nix mehr. Was genau ist dein Problem?
Wenn du den formatierten Text haben möchtest dann nimm halt die RTF Property. Wenn du den "Text" haben möchtest dann nimm die Text Property. Und wenn du den Text formatieren möchtets dann nimm SelectAll() und änder die SelectionXXX Properties.
Eine möglichkeit wäre das du via SelectAll() alles selektierst, und dann SelectionFont SelectionBackColor, SelectionForeColor etc. den Text so anpasst das er kein Steuerzeichen mehr enthält.
Im übrigen wenn du auf die Text-Property zu greifst, dann steht doch dort immer nur der Text drin, ist doch vom Typ String, oder irre ich mich da?
Der "normale" Text hängt doch an der Text-Property der RichTextBox...
Kleine Anmerkung. Ich habs bei mir mal ausprobiert und es geht ohne Probleme.
Ein vorschlag, kommentier mal alles überflüssige aus. Und dann schritt für schritt wieder ein, so findest du das am schnellsten. Und deine underscores am Anfang einer variable finde ich persönlich schrecklich.
Danke JBuechner,
das funktioniert ja bestens.
Hallo zusammen,
ich hab dies hier im Forum gefunden und könnte das sehr gut gebrauchen. Leider funzt das nicht richtig.
Und zwar hab ich 2 richTextBox Controls nebeneinander. Beide enthalten den selben Text. Wenn ich nun die Scrollbar betätige und dann wieder los lasse, dann wird auch die Scrollbar der rechten Seite korrekt gesetzt, daher hat sie die selbe Position, leider stimmt aber der Inhalt nicht mehr, daher müsste die obere Zeile der linken Seite ja genau der rechten Seite entsprechen. Selbst wenn es ein offset von einer Zeile wäre, würde mich das nicht stören, allerdings weicht das immer vollkommen ab, daher stimmt die anzeige der scrollbar zwar aber der angezeigte Inhalt nicht mehr.
Bewegt man danach die Scrollbar der rechten richTextBox dann synchronisiert sich der Inhalt wieder.
Weiß einer von euch woran das liegt, bzw wie man das beheben kann?
Das ist allerdings wahr das der Lookahead überflüssig ist, aber jetzt weiß RipperMac gleich was ein negativer Lookahead ist... 😃
Hallo RipperMac,
das seh ich auch so wie JAck30lena. Ein deutlich besserer weg ist das mit Regex zu lösen. Ich helf dir mal ein bisschen auf die Sprünge.
(?<!k)k{1,} Dieser regex Ausdruck findet alle k's die aufeinanderfolgen ohne das ein k folgt. Daher genau das was du willst. Man nennt das negativer Lookbehind,
sdfksdfksdfkksdfkkkksdfk
Und am Regex Object gibt es eine Replace Methode, die kannst du dir ja mal anschauen 😉
Falls es noch jemand gebrauchen kann, hier mal ein mögliche Lösung:
public static int[,] GetLongestCommonSubsequenceMatrix(string s1, string s2)
{
int[,] lcsMatrix = new int[s1.Length + 1, s2.Length + 1];
char letter1, letter2;
for (int i = s1.Length - 1; i >= 0; i--)
{
for (int j = s2.Length - 1; j >= 0; j--)
{
letter1 = s1[i];
letter2 = s2[j];
if (letter1 == letter2)
{
if ((i == s1.Length - 1) || (j == s2.Length - 1))
lcsMatrix[i, j] = 1;
else
lcsMatrix[i, j] = 1 + lcsMatrix[i + 1, j + 1];
}
else
{
if ((i == s1.Length - 1) && (j == s2.Length - 1))
lcsMatrix[i, j] = 0;
else if ((i == s1.Length - 1) && !(j == s2.Length - 1))
lcsMatrix[i, j] = Math.Max(0, lcsMatrix[i, j + 1]);
else if (!(i == s1.Length - 1) && (j == s2.Length - 1))
lcsMatrix[i, j] = Math.Max(lcsMatrix[i + 1, j], 0);
else if (!(i == s1.Length - 1) && !(j == s2.Length - 1))
lcsMatrix[i, j] = Math.Max(lcsMatrix[i + 1, j], lcsMatrix[i, j + 1]);
}
}
}
return lcsMatrix;
}
public static double GetDiffTreeFromBacktrackMatrix(int[,] arr, string s1, string s2)
{
int x = 0, y = 0;
while (x < s1.Length && y < s2.Length)
{
if (s1[x] == s2[y])
{
Console.WriteLine(string.Format(" {0}", s1[x]));
x++;
y++;
}
else if (arr[x, y + 1] > arr[x + 1, y])
{
Console.WriteLine(string.Format("- {0}", s2[y]));
y++;
}
else
{
Console.WriteLine(string.Format("+ {0}", s1[x]));
x++;
}
}
if (x < s1.Length)
{
for (int i = x; i < s1.Length; i++)
{
Console.WriteLine(string.Format("+ {0}", s1[i]));
}
}
else if (y < s2.Length)
{
for (int j = y; j < s2.Length; j++)
{
Console.WriteLine(string.Format("- {0}", s2[j]));
}
}
return (double)count / Math.Max(s1.Length, s2.Length) * 100;
}
//caller
public int Main()
{
int[,] arr = GetLongestCommonSubsequenceMatrix(s1, s2);
double d = GetDiffTreeFromBacktrackMatrix(arr, s1, s2);
}
Hallo herbivore,
es geht nicht darum das ihr den Fehler sucht, sondern das Ihr mir bestätigt das der Algorithmus das 'c' einmal als fehlend im string s1 und einmal als zuviel im string s2 korrekt berechnet, bzw. das dies nicht der Fall sein sollte.
Edit: Das hat mir sehr geholfen den Algorithmus zu verstehen.
Eigentlich sollte der Longest common subsequence algorithmus auch gehen, nur irgendwie liefert die nicht die richtigen Ergebnisse.
public void GetDiffTreeFromBacktrackMatrix(int[,] lcsMatrix, string s1, string s2, int i, int j)
{
if (i > 0 && j > 0 && s1[i - 1] == s2[j - 1])
{
GetDiffTreeFromBacktrackMatrix(lcsMatrix, s1, s2, i - 1, j - 1);
Console.WriteLine(" " + s1[i - 1]);
}
else
{
if (j > 0 && (i == 0 || lcsMatrix[i, j - 1] >= lcsMatrix[i - 1, j]))
{
GetDiffTreeFromBacktrackMatrix(lcsMatrix, s1, s2, i, j - 1);
Console.WriteLine("+ " + s2[j - 1]);
}
else if (i > 0 && (j == 0 || lcsMatrix[i, j - 1] < lcsMatrix[i - 1, j]))
{
GetDiffTreeFromBacktrackMatrix(lcsMatrix, s1, s2, i - 1, j);
Console.WriteLine("- " + s1[i - 1]);
}
}
}
public static int[,] GetLongestCommonSubsequenceMatrix(string s1, string s2)
{
int[,] lcsMatrix = new int[s1.Length, s2.Length];
char letter1, letter2;
for (int i = 0; i < s1.Length; i++)
{
for (int j = 0; j < s2.Length; j++)
{
letter1 = s1[i];
letter2 = s2[j];
if (letter1 == letter2)
{
if ((i == 0) || (j == 0))
lcsMatrix[i, j] = 1;
else
lcsMatrix[i, j] = 1 + lcsMatrix[i - 1, j - 1];
}
else
{
if ((i == 0) && (j == 0))
lcsMatrix[i, j] = 0;
else if ((i == 0) && !(j == 0))
lcsMatrix[i, j] = Math.Max(0, lcsMatrix[i, j - 1]);
else if (!(i == 0) && (j == 0))
lcsMatrix[i, j] = Math.Max(lcsMatrix[i - 1, j], 0);
else if (!(i == 0) && !(j == 0))
lcsMatrix[i, j] = Math.Max(lcsMatrix[i - 1, j], lcsMatrix[i, j - 1]);
}
}
}
return lcsMatrix;
}
//call
string s1 = "ich weiß e nicht genau";
string s2 = "ich weiß es nict genau";
GetDiffTreeFromBacktrackMatrix(GetLongestCommonSubsequenceMatrix(s1, s2), s1, s2, s1.Length, s2.Length);
Ich möchte hier als Ergebniss nur haben (s) zuwenig, (h) zuviel. Aber das Ergebniss lautet +s -c -h +c. Aber das c kommt doch in beiden vor, das soll gar nicht mit matchen. Anscheinend steig ich noch nicht richtig hinter den Algorihtmus. Ein weiteres Problem ist das wenn die Strings beide unterschiedliche längen haben, und das letzte Zeichen nicht überein stimmt dann gibt es ein index out auf bounds exception lcsMatrix[i - 1, j] weil ja j ein zu groß ist. Ich muss gestehen ich habe den Algo von hier.
Weiß einer von euch meinen Fehler?
Das ist natürlich eine gute Idee, ich werd das mal probieren.
Ja soweit so gut, das problem nur ist das es in beide Richtungen gehen muss, daher es gibt strings die sind in s1 und in s2 nicht und andersrum. Irgendwie hab ich da eine denkblockade
Hallo ich benötige einen kleinen Tipp bezüglich eines Algorithmus den es sicher schon gibt.
Ich möchte 2 Zeichenketten nach einem Muster überprüfen. ein Beispiel soll dies verdeutlichen:
string s1 = "tokenblakroneiikkpdp"
string s2 = "tokenbkroniikkAutopdp"
Raus kommen soll nun folgendes. Das im string 2 das "la" fehlt, sowie das "e" bei krone, sowie das Auto zuviel drin ist. Daher einfach eine Liste mit z.B. Point Objekten, mit index und Length.
Gibt es dafür schon was fertiges was man nur noch anpassen muss?
Ok habs grad gefunden.
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length == 0)
return "";
return ((AssemblyProductAttribute)attributes[0]).Product;
Cool das mit doch schon mal eine halbwegs gute Lösung. Kannst du mir noch kurz sagen wo die Property dran klebt, sonst muss ich wieder mit dem Reflector so lange suchen 😃
Ich meine eine CLR dll also eine DLL die zur Runtime gehört, nicht eine DLL die mit .NET übersetzt wurde. Zum Beispiel die System.dll
Nicht das ich mich irre, aber das ist doch eine CLR der .NET Runtime?
Hallo zusammen,
gibt es eine Möglichkeit anhand einer Assembly festzustellen ob sie eine Runtime Assembly ist, daher zur .NET Runtime gehört? Mit dem GAC geht es leider nicht, da ja auch ganz normale Assebmlies dort referenziert sein können.
Das war auch meine erste Idee, aber gibt es sowas nicht schon fertig?
Ich suche ein Control das wie ein Grid funktioniert, jedoch auf der ersten Spalte ein Treeview darstellt. Die weiteren Spalten enthalten dann die Daten zu den aufgeklappten knoten und Elementen. Es gibt sowas sicher schon, ich weiß nur nicht nach was ich suchen muss 😦
Kann mir jemand helfen?
Hallo ich bins noch mal. ICh hab ein kleines Problem bezüglich dem was golo vor hatte. Ich hab mir mal eine Regel geschrieben die mir alle Methoden anzeigt welche keinen "caller" haben. In der public override ProblemCollection Check(Member member) check ich ob dort eine methode als member übergeben wird. Wenn ja wie kann ich jetzt prüfen ob im gesamten Code diese Methode nun gecalled wird oder nicht?
@Golo Roden
kennst du ein gutes Turorial um mal eine FxCop regel selber zu schreiben? bzw. kannst du die regel die du für das nicht aufrufen der Methoden definieriert hast hier veröffentlichen?
Hallo zusammen,
ich suche ein Tool dem ich eine .NET Assembly (exe,dll) in die Hand drücken kann, und es mir sagt welche .NET Version ich zum ausführen brauche. Gibt es sowas schon, oder muss ich jede Reference einzelln durch gehen?
Problem ist nämlich wenn die besagt Assembly wieder eine refernce hat auf eine andere Assembly die Ihrerseits eine System.dll in V3.5 nutzt braucht, aber die eigentlich Assembly nur 2.0. Das ganze kann man noch weiter spinnen...
Wenn es kein Tool gibt, weiß einer von euch wie ich das schnell überprüfen kann?
Das standard MenüItem hat keine Icon Property. Daher musst du selber dafür sorgen. Leite dich also von MenuItem ab und füge eine solche Property hinzu. Dann musst du das OwnerDraw Flag noch setzen und im OnPaint den Content selber zeichnen.
Ich hab sowas schon mal gebastelt, ich schau mal ob ichs finde...
Ehrlich gesagt versteh ich dein Problem nicht! Könntest du das noch mal genauer spezifizieren wo das Problem liegt?
Ja das kann ich schon. Aber das hat keinerlei Auswirkungen 😃
Irgendjemand noch Ideen?
Guckst du in TreeNode.ImageIndex-Eigenschaft.
So wie ich das sehe fügst du hier doch immer wieder das Icon zu der Liste hinzu...
foreach (var kanal in teiln.channels)
{
il.Images.Add(new Icon("uncrypt.ico"));
Hallo zusammen,
ich habe ein kleines DragDrop Cursor Problem. Ich hab auch schon im Forum gesucht, das hat mir zwar geholfen, aber bei einem Problem komme ich nicht weiter.
Ich habe eine Control das von Control erbt und diesen kann man Bilder via drag drop von z.B. einem Explorer adden. Dazu hab ich das OnDragEnter und das OnDragDrop überschieben und dann das bild geaddet. Funzt alle bestens.
Dann wollte ich den Cursor beim dragen so verändern das es das Bild als vorschau sehe. Dem Cursor.Current diesen neuen Cursor zuzuweisen ist nicht das Problem. Daher wenn ich es z.b. im MouseMove event einmal zuweise, dann wird auch der Cursor angezeigt.
Das problem kommt das ich beim OnDragEnter den Cursor setze. Allerdings interessiert das den Cursor nicht, den der zeigt einfach den standard OnDragOver Cursor an. Ich hab mich auch schon auf das GiveFeedback event der Form und auch meines Controls angemeldet um dort in den Eventargs das UseDefaultCursors auf false zu setzen. Das Problem ist das ich in diesem Event nie lande wenn ich drage.
Muss ich dafür noch irgendein Flag setzen? Mache ich irgendwas falsch?
//subscribed by the form and the picture control
this.GiveFeedback += new GiveFeedbackEventHandler(PictureDrawerGiveFeedback);
void PictureDrawerGiveFeedback(object sender, GiveFeedbackEventArgs e)
{
e.UseDefaultCursors = e.Effect != DragDropEffects.Copy;
}
//dll import from the user32.dll to change the cursor
public struct IconInfo
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref IconInfo icon);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
public static Cursor CreateCursor(Bitmap bmp,
int xHotSpot, int yHotSpot)
{
IconInfo tmp = new IconInfo();
GetIconInfo(bmp.GetHicon(), ref tmp);
tmp.xHotspot = xHotSpot;
tmp.yHotspot = yHotSpot;
tmp.fIcon = false;
return new Cursor(CreateIconIndirect(ref tmp));
}
//code for the picture control
protected override void OnDragEnter(DragEventArgs drgevent)
{
string[] files = (string[])drgevent.Data.GetData(DataFormats.FileDrop);
if (files.Length == 1)
{
string extension = Path.GetExtension(files[0]);
if (extension == ".jpg" || extension == ".bmp"
|| extension == ".png" || extension == ".gif")
{
drgevent.Effect = DragDropEffects.Copy;
//change the current cursor for a test to a static image
m_isDragOperation = true;
Bitmap bitmap = new Bitmap(Resources.pic1, 32, 32);
Cursor.Current = CreateCursor(bitmap, 0, 0);
}
}
base.OnDragEnter(drgevent);
}
protected override void OnDragDrop(DragEventArgs drgevent)
{
string[] files = (string[])drgevent.Data.GetData(DataFormats.FileDrop);
string extension = Path.GetExtension(files[0]);
Image image = new Icon(files[0]).ToBitmap();
this.AddPicture(new PictureContent(image,
this.PointToClient(new Point(drgevent.X, drgevent.Y)),
image.Size,
0));
base.OnDragDrop(drgevent);
}
Dieses Thema hatten wir schon ein paar mal. Die Foren suche hätte dir weiter geholfen. Siehe dazu hier.
Ok dann kann ich das separat behandeln, und auch die Daten typisiert machen. Besten Dank für den Denkanstoß.
Ja genau da ist ja das Problem. Die Items Eigenschaft ist eine ObjectCollection. Dort kann ich keine BindingList dran binden. Ich will ja nur das die Items Eigenschaft auf einen Datentyp begrenzen, ohne die OnPaint ändern zu müssen. Mir ist auch klar das man in eine ObjectCollection alles rein stecken kann, ich möchte aber dem Anwender der Klasse auf einen bestimmten Datentyp beschränken.
@ herbivore
Zwecks des BindingList, kannst du mir da bisschen auf die Sprünge helfen, weiß net wie du das meinst...
Hallo zusammen,
ich hab eine Frage bezüglich folgendem. Ich möchte eine ListBox die keine Items vom Typ Object annimmt, sondern typisiert ist. Daher in der Add Methode der Items Property soll einzig eine bestimmter Datentyp möglich sein. Wie würdet ihr das Designen, daher wenn ich eine eigene Liste verwalte muss ich auch selber zeichnen. Wenn ich eine ObjectCollection ableite kann ich zwar eine neue Add methode definieren, aber die base.Add kann ich nicht verdecken. Irgenwie fällt mir keine einfach Lösung ein.
hab ein kleines performance problem mit einem großen usercontrol (beihaltet ca 600 Controls).
Also 600 Controls sind viel zu viele wie schon meine vorredner gesagt haben. Füg doch mal ein bild hinzu oder sag um welche Controls es sich handelt, dann können wir dir auch gezielte Tips geben wie man das besser und performanter umsetzen kann.
Ein und Ausgänge klingt ja erstmal nach "CheckBoxen"...?