Rekursion.

Du brauchst eine eigene Methode, die einen Ordnerpfad als Parameter entgegennimmt und die Anzahl der enthaltenen Dateien zurückgibt. Sollte der Pfad weitere Ordner enthalten, lässt du die gleiche Methode mit dem neuen Ordner aufrufen. Das umschließt du mit einen try-Block und fängst die Ausnahme ab, damit solche System-Ordner übersprungen werden.

Du findest sicherlich genug Beispiele dazu im Internet.

...zur Antwort
C# Focus bei UserControl?

Hallo,

ich hab ein Problem mit dem Focus eines UserControls. Und zwar bekommt das UserControl trotzdem den Focus obwohl alle seine ChildControls nicht focusierbar sind. Ich hab hier mal ein kleines Beispiel erstellt, zum testen einfach ein neues Windows Forms Project anlegen und den Code in den Source Code der Form kopieren.

using System.Windows.Forms;

namespace testUserControl
{
  using System.Diagnostics.Eventing.Reader;

  public partial class Form1 : Form
  {
    private testControl testControl1;
    private testControl testControl2;
    private testControl testControl3;
    
    public Form1()
    {
      InitializeComponent();

      this.testControl1 = new testUserControl.testControl();
      this.testControl2 = new testUserControl.testControl();
      this.testControl3 = new testUserControl.testControl();

      this.testControl1.Location = new System.Drawing.Point(24, 27);
      this.testControl1.Name = "testControl1";
      this.testControl1.Size = new System.Drawing.Size(150, 37);
      this.testControl1.TabIndex = 0;


      this.testControl2.Location = new System.Drawing.Point(24, 71);
      this.testControl2.Name = "testControl2";
      this.testControl2.Size = new System.Drawing.Size(150, 45);
      this.testControl2.TabIndex = 1;


      this.testControl3.Location = new System.Drawing.Point(24, 136);
      this.testControl3.Name = "testControl3";
      this.testControl3.Size = new System.Drawing.Size(150, 47);
      this.testControl3.TabIndex = 2;

      this.Controls.Add(this.testControl3);
      this.Controls.Add(this.testControl2);
      this.Controls.Add(this.testControl1);

      testControl2.Disable();
    }
  }

  public class testControl : UserControl
  {
    private TextBox test;

    private Label TestLabel;

    public testControl()
    {
      this.test = new TextBox();
      this.test.Name = "TextBox";
      this.test.Location = new System.Drawing.Point(100, 5);
      this.test.Size = new System.Drawing.Size(80, 17);

      this.TestLabel = new Label();
      this.TestLabel.Name = "Label";
      this.TestLabel.Text = "Test";
      this.TestLabel.Location = new System.Drawing.Point(10, 5);
      this.TestLabel.Size = new System.Drawing.Size(50, 17);

      this.Controls.Add(this.test);
      this.Controls.Add(this.TestLabel);
    }

    public void Disable()
    {
      this.test.Enabled = false;
    }
  }
}

Ich weiß das das Design jetzt nicht schön aussieht aber das ist auch egal. Um was es mir jetzt geht ist, das wenn ich mit tab durchgehe das 2. Control trotzdem den Focus bekommt obwohl es aus einem lable und einer deaktivierten TextBox besteht. Warum ist das so? Und wie kann ich das umgehen?

Danke für alle Antworten.

...zur Frage

Das Usercontrol ist in Sachen Fokus eine seltsame Geschichte.

Am einfachsten wäre es, die Enabled-Eigenschaft auf False zu setzen. Dabei werden automatisch alle Child-Controls auch auf Enabled = False gesetzt und ist über den Tab nicht mehr zu erreichen.

this.SetStyle(ControlStyles.Selectable, false) wäre auch eine Möglichkeit, aber dann kannst du nicht mehr von einer TextBox des UserControls in eine andere TextBox eines anderen UserControls mit Tab springen.

Gibt sicher noch andere Möglichkeiten, da wird es dann aber etwas komplizierter.

...zur Antwort

Zahl1 ist der Inhalt, bevor du auf eine Rechenoperation klickst. Zahl2 ist der Inhalt, bevor zu auf das Gleichheitszeichen klickst. Das Ergebnis wird dann in Zahl1 zusammengefasst und angezeigt.

Wenn man programmieren möchte, hilft es häufig sich das Problem auf Papier klar zu machen - oder in einem Textverarbeitungsprogramm am PC - oder ... je nachdem, was einem lieber ist.

...zur Antwort

Zuerst zu deinem Problem: Application.DoEvents steht an der falschen Stelle. Wenn dich die Erklärung für das Verhalten interessiert, dann lies weiter, ansonsten springe zum nächsten Absatz nach der Liste. Schritt für Schritt sieht der Ablauf so aus:

  • Erster Durchlauf: Du setzt den Wert auf 10 und weist diesen Wert dem Label zu. Das Label hat nun von Windows eine Anforderung zum Neuzeichnen erhalten und wird diese ausführen, sobald die MessageQueue verarbeitet wird. (Das passiert noch nicht, weil der aktuelle Thread noch in der For-Schleife arbeitet.)
  • Im zweiten Durchlauf setzt du den Wert auf 10 und erlaubst die Abarbeitung der MessageQueue durch Application.DoEvents. Das Label darf nun seinen Inhalt aktualisieren und zeigt den Wert 10 an. Erst dann weist du dem Label den neuen Wert 20 zu. Gleiches Spiel: die Anforderung zum Neuzeichnen landet in der MessageQueue und wird bei der nächsten Abarbeitung ausgeführt. Aber auch das passiert erst im nächsten Durchlauf.
  • Im vorletzten Durchlauf ist der Wert der ProgressBar 90 und das Label darf dann erst seine 80 aus der vorherigen Anforderung zeichnen.
  • Im letzten Durchlauf passiert das gleiche. Allerdings ist der Thread danach frei (kein Thread.Sleep) und kann sofort die MessageQueue erneut abarbeiten und somit die 100 anzeigen. Die 90 wird also vorher angezeigt, aber nur für den Bruchteil einer Sekunde (wenn überhaupt).

Wenn du Application.DoEvents nach der Wertzuweisung des Labels schreibst, funktioniert es wie gewollt.

Nun zum anderen Problem: Nichts ist nerviger als ein simulierter Fortschritt. Eine ProgressBar, die ihren Wert in Abhängigkeit einer (zur Entwurfszeit) definierten Zeit verändert hält den gesamten Programmablauf auf und hat ohne Multithreading wenig Sinn.

...zur Antwort

Typischerweise (sofern nichts geändert wurde) wird die Anwendung beendet, wenn die Startform geschlossen wird.

Es kann sein, dass das Startformular versteckt wurde (Hide) und somit nicht geschlossen werden kann. Dadurch bleibt die Anwendung aktiv.

Du könntest zum Test einfach mal schauen, was dir "My.Application.OpenForms" so ausgibt, wenn dein Fenster geschlossen wird. Damit lässt du dir alle geöffneten Fenster anzeigen.

...zur Antwort

Rechtsklick auf die Toolbox und "Elemente auswählen" anklicken. Dann erscheint ein Fenster. Dort suchst du nach dem PowerPacks, wählst deine gewünschten Elemente aus und bestätigst das Fenster.

...zur Antwort

Selbst bei der Verwendung von Tabs brauchst du das ActiveX-Steuerelement nicht.

Du kannst ein TabControl verwenden, bei dem jede TabPage ein WebBrowser-Control enthält. Willst du einen neuen Tab erzeugen, dann brauchst du nur eine neue TabPage dem TabControl hinzufügen und platzierst ein WebBrowser-Control auf die neue TabPage.

Dann brauchst du dich nicht mit irgendwelchen Kompatibilitäten rumärgern.

...zur Antwort

Du hast mit deiner Vermutung der "langsamen Animation" recht.

Seit Windows Vista ist das Redesign der Progressbar für ein solches Verhalten verantwortlich. Wird der Wert erhöht, dann wird durch Windows eine Animation ausgelöst, die diese Änderung progressiv anzeigt. Je schneller der Wert erhöht wird, desto mehr scheint die Animation hinterher zu hängen.

Eine Möglichkeit diese Animation zu umgehen wäre es beispielsweise den Wert nach dem Erhöhen wieder zu verringern. Zum Beispiel so:

if (progressBar1.Value == progressBar1.Maximum - 1)
{
progressBar1.Increment(1);
}
else
{
progressBar1.Increment(2);
progressBar1.Increment(-1);
}
...zur Antwort

Was ist ein Picture-Button?

Wenn du mit Steuerelementen arbeitest, dann haben diese eine Location-Eigenschaft. Die gibt die Position von der oberen linken Ecke des übergeordneten Containers (bei dir möglicherweise die Form) zur oberen linken Ecke des Steuerelementes an.

Wenn es dir um die Logik der unterschiedlichen Programmzweige bei einem Klick geht, dann verwende eine zusätzliche Variable. Ist diese leer, dann wurde das erste mal geklickt und du kannst ihr einen Wert zuweisen (nämlich die Position). Ist diese nicht leer, dann wurde bereits einmal geklickt und sie hat einen Wert. Dann kannst du den Button auf diese Position setzen.

Oder wie auch immer; kann sein, dass ich dein Problem nicht ganz verstanden habe.

...zur Antwort

Du kannst deine Eingabe auch dynamisch kompilieren. Das heißt die Analyse übernimmt der Compiler, wodurch du selbst keinen Parser schreiben musst. (Ergibt das gleiche, als würdest du die Eingabe fest programmieren und das Programm kompilieren/starten.)

Public Function Parse(input As String) As Boolean
Dim provider As New VBCodeProvider
Dim parameters As New CodeDom.Compiler.CompilerParameters
parameters.GenerateInMemory = True
parameters.GenerateExecutable = True

' Programmcode erzeugen, der dynamisch kompiliert werden soll. Der übergebene Text wird dabei
' als Programmcode erkannt und entsprechend kompiliert.
Dim programCode As New System.Text.StringBuilder
programCode.AppendLine("Imports System.Windows.Forms")
programCode.AppendLine("Namespace RuntimeCompiled")
programCode.AppendLine(" Public Class RuntimeCompiledClass")
programCode.AppendLine(" Public Shared Sub Main()")
programCode.AppendLine(" End Sub")
programCode.AppendLine(" Public Shared Function Parse() As Boolean")
programCode.Append(" Return ")
programCode.AppendLine(input)
programCode.AppendLine(" End Function")
programCode.AppendLine(" End Class")
programCode.AppendLine("End Namespace")

' Programm kompilieren.
Dim compiledResult As CodeDom.Compiler.CompilerResults = provider.CompileAssemblyFromSource(parameters, programCode.ToString)
If compiledResult.Errors.HasErrors Then Throw New InvalidOperationException

' Methode mittels Reflection ermitteln, aufrufen und das Ergebnis zurückgeben.
Dim compiledAssembly As Reflection.Assembly = compiledResult.CompiledAssembly
Dim classType As Type = compiledAssembly.GetType("RuntimeCompiled.RuntimeCompiledClass")
Dim method As Reflection.MethodInfo = classType.GetMethod("Parse")
Return CBool(method.Invoke(Nothing, Nothing))
End Function

So würde die Methode aussehen. Der Aufruf wäre dann einfach:

Dim input As String = TextBox1.Text
input = input.Replace("1", "True")
input = input.Replace("0", "False")

Dim result As Boolean = Parse(input)
MessageBox.Show(result.ToString)

Der Vorteil ist, dass du damit komplizierte Anweisungen beliebig verschachteln kannst. Der Nachteil ist, dass damit jede Art von Code kompiliert wird. Es wäre daher möglich Schadcode auszuführen.

...zur Antwort

Hat die Bilddatei den gleichen Namen wie die vorherige, gelöschte Datei?

Wenn ja, dann gehe ich bei Visual Studio 2010 immer wie folgt vor: Im Projektexplorer lösche ich die Datei aus dem Resources-Verzeichnis. Dann gehe ich in die Projekteigenschaften und lösche dort den Eintrag. Weil VS2010 irgendwie immernoch die Bilddaten im Speicher liegen hat, schließe und öffne ich die Projektmappe erneut und kann somit das Bild neu importieren.

Eventuell ist das Schließen und Öffnen in den neuen Versionen von VS nicht nötig. Wichtig für den Ressourcenkontext, wie du es nennst, ist es den Eintrag in den Projekteigenschaften unter "Ressourcen" zu entfernen (dort muss oben statt "Zeichenfolgen" "Bilder" stehen).

...zur Antwort

Nach welcher Logik soll die Zahlenkette erstellt werden? Sollen die Werte der Matrix zweilenweise oder spaltenweise in die Zahlenkette übertragen werden?

Wenn du diese Frage geklärt hast, dann kannst du zwei For-Schleifen erstellen. Eine für die Zeilen (Laufvariable i) und eine für die Spalten (Laufvariable j) - oder anders herum, je nach Anforderung. Dann einfach das Element mit dem Index [i, j] der Zahlenkette hinzufügen.

...zur Antwort

Visual Studio ist abwärtskompatibel. Was du beschrieben hast ist aber keine Abwärtskompatibilität, sondern eher das Gegenteil. Abwärtskompatibel heißt, dass eine Version von Visual Studio alle Projekte aus älteren Versionen öffnen kann - und das ist bei Visual Studio der Fall. Mit VS2015 kannst du Projekte von VS2010 öffnen.

Visual Studio 2010 kann aber beispielsweise keine Projekte von Visual Studio 2015 öffnen, weil diese nicht kompatibel sind. Visual Studio 2013 hingegen kann solche Projekte öffnen (da gab es keine Breaking Changes für Projektdaten).

Das bedeutet aber nicht, dass du diese auch fehlerfrei kompilieren kannst. Eine neue Version von Visual Studio heißt meist auch ein aktuellerer Compiler, der zusätzliche Anweisungen kennt. Vorallem die .NET Sprachen werden oft weiterentwickelt und erhalten neue Anweisungen, die es in den älteren Versionen der Sprachen nicht gab. Das ist dann von der Programmierung abhängig, ob diese Projekte fehlerfrei geöffnet und kompiliert werden können.

...zur Antwort
Weitere Inhalte können nur Nutzer sehen, die bei uns eingeloggt sind.