Laden...

Forenbeiträge von Th69 Ingesamt 5.076 Beiträge

17.04.2025 - 15:47 Uhr

Ja, so sollte es funktionieren.

Kannst es ja danach mit dem analogen Getter-Zugriff überprüfen:

int pageSize = (int)oCommand.InvokeMember("Properties", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.GetProperty, null, oCommandInst, new object[]{"Page Size"} ); // bzw. die Variable bfGetProperty verwenden ;-)
17.04.2025 - 13:07 Uhr

OK, ich versuche es mal direkt hier im Editor (da ich jetzt kein Projekt dazu erzeugen möchte):

var bfGetProperty = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.GetProperty;

// Code for objRS.Fields["samaccountname"]
object field = oRS.InvokeMember("Fields", bfGetProperty, null, objRS, new Object[] { "samaccountname" } );

// Code for field.Value
object value = field.GetType().InvokeMember("Value", bfGetProperty, null, field, null);

Und zu dem Fehler bzgl. BindingFlags.SetField schreibe ich jetzt nichts weiteres...

17.04.2025 - 11:21 Uhr

Ich hatte dir doch oben in meinem "Edit" den Code aus der Doku gezeigt, wie man eine Index-Eigenschaft bei InvokeMember benutzt (also als Array bei args angeben). Bei einem Lesezugriff also nur ein einelementiges Array mit dem Index angeben.

17.04.2025 - 10:13 Uhr

Der Fehler ist doch klar: Properties ist eine Eigenschaft, also mußt du BindingFlags.SetProperty verwenden (sowie die anderen erforderlichen BindingFlags).

Und bei ErgebnisRecordSet.Fields["name der spalte"].Value mußt du halt sequentiell vorgehen, also erst ErgebnisRecordSet.Fields["name der spalte"]und dann für das Objekt auf Value zugreifen.

Ich kann zwar das Recordset ansprechen und bekomme auch das Fields Objekt, kann aber nicht auf die Inhalte zugreifen oder weis nicht, wie ich das machen soll.

Dann bist du doch auf dem richtigen Weg. Um den Type für das Fields Objekt zu bestimmen, einfach field.GetType()(wenn die Variable field heißt) benutzen und damit dann InvokeMember (oder aber GetProperty, SetProperty, ...) aufrufen.

Schau dir ansonsten die Beispiele dazu in der Doku an.

15.04.2025 - 19:36 Uhr

Bei Type.InvokeMember kannst du beim Parameter args (d.h. bei deiner gewählten Überladung der letzte Parameter) ein Array mit dem zu setzenden Wert angeben, also z.B. new Object[] { 100 }.

Wie man jedoch dort auf eine Index-Eigenschaft zugreift, weiß ich nicht. Evtl. müßtest du dann stattdessen Type.GetProperty verwenden und dort dann beim Parameter types den Indexdatentyp angeben und anschließend für den Rückgabewert PropertyInfo.SetValue aufrufen.

Edit:

Es geht anscheinend doch mit InvokeMember. Unter "Hinweise" steht:

Sie können auch verwenden Type.InvokeMember , um eine Position in einem Array festzulegen, indem Sie den Index des Werts und dann den nächsten Wert mithilfe von Code wie dem folgenden angeben:

typeof(C).InvokeMember("F", BindingFlags.SetField, null, c, new Object[] {1, "b"});

Dadurch wird die Zeichenfolge "z" im Array, das F enthält, in die Zeichenfolge "b" geändert.

(Ich lieben automatisch Translationen ;- )

PS: Anstatt die BindingFlags immer wieder einzeln anzugeben, solltest du einfach eine lokale Variable dafür erstellen.

04.04.2025 - 14:27 Uhr

Verwende auch du die C#-Tags bei deinen Beiträgen (kannst es auch nachträglich editieren):

oCommand.InvokeMember("ActiveConnection", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.SetProperty, null, oCommandInst, args);

Welchen genauen Fehler gibt es denn, wenn du es bei einem Testprojekt verwendest?

04.04.2025 - 12:45 Uhr

Das Äquivalent zu CreateObject in .NET ist Activator.CreateInstance(zusammen mit Type.GetTypeFromProgID), s.a. Equivalent code of CreateObject in C#.

Dies wird dann auch von der ADODB-Klasse intern benutzt und entsprechend typsicher zur Verfügung gestellt.
Mit dem Schlüsselwort dynamic kannst du dann auf COM-Objekte zugreifen (auch wenn die Typen und Methoden nicht per Referenz eingebunden sind).

Ob das jedoch alles innerhalb einer C#-Methode funktioniert, testest du am besten an einer eigenen (Konsolen-)Anwendung aus - und kopierst anschließend den gesamten Code der Methode.

04.04.2025 - 11:39 Uhr

Um mit .NET auf LDAP zuzugreifen, wird ADODB benötigt: ADODB Connection in .NET Application Using C# (also auch eine externe Referenz - und ich bezweifle, daß diese standardmäßig bei deiner Anwendung dabei ist).

Der Code dazu sieht dann so aus: How do I query Active Directory using C# and ADODB?

Edit:
Weißt du denn, welche Provider/Datenbankzugriffsklassen dir zu Verfügung stehen?

23.03.2025 - 11:54 Uhr

Deine Namen sind aber auch m.E. ein bißchen zu komplex - als VM-Eigenschaft würde ich es einfach IsArea1Activebzw. IsArea1Checked nennen (weder das Bind noch der Control-Type ChBox sind hier sinnvoll).

22.03.2025 - 08:41 Uhr

ODBC ist aber eine veraltete Technologie!

Einfach direkt den ADO-Treiber MySqlConnector: High-Performance .NET MySQL Driver verwenden.


Und beachte bei dem Projekt die Trennung von UI, Logik und Datenzugriff (also in dieser Schicht den DB-Zugriff durchführen): [Artikel] Drei-Schichten-Architektur

20.03.2025 - 11:08 Uhr

Man kann in VS unter "Ausnahmeeinstellungen" angeben, daß bei bestimmten Exceptions die Codeausführung unterbrochen wird: Verwalten von Ausnahmen mit dem Debugger in Visual Studio 
Und dann im Call-Stack nachschauen, welcher Code da aufgerufen wurde.

15.03.2025 - 09:26 Uhr

Sorry, aber der switch ist hier komplett unnötig, da die einzelnen Zellenelemente einfach als object weitergegeben werden, d.h. die aufrufende Methode müßte genauso wieder einen switch anwenden, um auf die Elemente der XLTBL zuzugreifen.

So, wie T-Virus geschrieben hat, sollte man spezifische Klassen (mit konkreten Datentypen) benutzen, um die Daten auszulesen.

15.03.2025 - 09:14 Uhr

Noch zu deinem letzten Code: du hättest, genauso wie du es bei den teams gemacht hast, die Spielpaarungen auch in der Start-Methode initialisieren müssen (genau so wie es auch Caveman in seinem Code gemacht hat).

Das MVVM-Toolkit (s. Einführung in das MVVM-Toolkit) nimmt dir einiges an Code ab, welchen du ansonsten selber für deine MVVM-Projekte erstellen (bzw. aus anderen Projekten kopieren) müßtest, z.B. die ObservableObject-Klasse als Implementierung der INotifyPropertyChanged-Schnittstelle (bei anderen MVVM-Projekten heißt diese Klasse häufig ViewModelBase bzw. BaseViewModel) sowie RelayCommand für die ICommand-Schnittstelle.

Zusätzlich zu dem MVVM-Artikel solltest du dir ein paar MVVM-Tutorials (am besten auf Grundlage des WPF MVVM-Toolkits) anschauen, um die Zusammenhänge besser zu verstehen (am Anfang kann dies alles verwirrend sein).


Noch bzgl.

Den Button zur Formatierung habe ich jetzt gesehen!

Aber nicht für deinen Code angewendet...

14.03.2025 - 16:26 Uhr

Du hast recht, ich kann die ZIP-Datei auch nicht öffnen.

Ich habe aber noch diesen Artikel gefunden: Autocomplete Menu (die ZIP-Dateien lassen sich herunterladen und auch öffnen).

14.03.2025 - 16:05 Uhr

Du hast dort immer noch keine Klasse Spielpaarung erstellt.

Und dann, wie schon geschrieben, davon eine Liste erstellen:

List<Spielpaarung> pairs = new()
{
  new Spielpaarung(teams[0], teams[1]),
  new Spielpaarung(teams[2], teams[3])
};

listView.ItemsSource = pairs;

Mit einem passenden Konstruktor (mit zwei Mannschaft-Objekten), sowie den zwei zugehörigen Eigenschaften.

Alternativ kann man auch record benutzen, z.B.

public record Spielpaarung(Mannschaft Team1, Mannschaft Team2);

Dabei werden automatisch die zugehörigen Eigenschaften Team1und Team2 vom Compiler erzeugt. Und im XAML-Code dann diese Eigenschaften benutzen (Groß-/Kleinschreibung beachten).

PS: Für die Code-Formatierung gibt es extra einen Button im Forumseditor (rechts neben der Schriftfarbe)!

14.03.2025 - 10:45 Uhr

Brauchst du beide Einträge? Oder geht es dir nur darum, daß die Groß-/Kleinschreibung erhalten bleibt, dann s. How to make winforms textbox autocomplete correct capitalisation?

Alternativ habe ich noch AutoComplete TextBox with SubString search, similar to SQL Like or Contains gefunden, mit einer eigenen Implementierung für die AutoComplete-Funktionalität (auch wohl mit einer CaseSensitive-Suche). Um die ZIP-Datei herunterzuladen, musste ich explizit "Ziel speichern unter..." auswählen, ein normaler Linksklick hat nicht funktioniert.

14.03.2025 - 10:22 Uhr

Du brauchst dafür eine weitere Klasse Spielpaarung, in der du dann zwei Eigenschaften für die Mannschaften (z.B. Heimmannschaft und Auswaertsmannschaft- oder einfach, wie unten im Code benutzt, Team1 und Team2;-) erstellst.

Und dann davon eine Liste erstellen und an das ListView binden.

Das Binding sieht dann so aus:

<Image Source="{Binding Team1.LandFlagge}" Height="16" Width="16"/>
<TextBlock Text="{Binding Team2.LandName}"/>

<TextBlock Text="{Binding Team2.LandName}"/>
<Image Source="{Binding Team2.LandFlagge}" Height="16" Width="16"/>

Außerdem solltest du für WPF das MVVM-Pattern benutzen, s. [Artikel] MVVM und DataBinding.


PS: Du solltest deinen Code hier im Forum passend mit den Code-Blöcken formatieren.

06.03.2025 - 16:52 Uhr

Hallo und willkommen,

nein, ein Label kann nur eine Textfarbe per ForegroundColor darstellen. Die eine Alternative hast du ja schon selbst genannt, die andere wäre den Text per [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox) darzustellen, s.a. Graphics.DrawString.

Edit:

Noch eine weitere Alternative wäre die RichTextBox, in der kann man einzelne Texte verschiedenfarbig darstellen (diese sollte dann aber ReadOnly sein, damit der User den Text nicht ändern kann).

18.02.2025 - 11:15 Uhr

Dafür gibt es extra den Forenbereich Code-Reviews (beachte aber dessen Regeln).

14.02.2025 - 15:15 Uhr

Ich meinte anstatt des UniformGrid. Und warum hast du das ItemsControl noch mal innerhalb eines StackPanels?

Ich meinte ein ItemsControl in Zusammenhang mit einem Canvas, s. z.B.

Bei deinem bisherigen Ansatz würden doch bei Abschuß eines feindlichen Raumschiffs die restlichen dann zusammengeschoben werden (wenn das Raumschiff aus der Liste gelöscht wird).

13.02.2025 - 16:00 Uhr

Zitat von Monokuma

Ich möchte eine Collection aus Rectangles an einen Container binden, der diese dann in einem gleichmäßigen Abstand anzeigt. Ein UniformGrid hat einen Abstand am Rand, den ich nicht möchte.

Bist du sicher, daß der Rand von dem UniformGrid kommt und nicht von der Einbettung in das äußere ItemsControl? Die Bilder in #467 – Use a UniformGrid for Evenly Spaced Rows and Columns zeigen keine inneren Ränder.
Mittels Margin müßtest du diese auf 0setzen können:

 <UniformGrid Rows="1" Margin="0" Width="500"/>

Zusätzlich will ich auch in Zukunft die Breite des Containers dynamisch anpassen, je nachdem, ob ein Element am Rand aus der Collection verschwindet.

Dazu brauchst du doch nur die Breite per Binding an eine Eigenschaft deines VM binden.

Edit:
Wäre ein Canvas für die Darstellung nicht besser geeignet (und das VM übernimmt dann die Positionierung der Objekte)?

08.02.2025 - 09:38 Uhr

Die zu bindende Klasse muß einen parameterlosen Konstruktor besitzen: Editable DataGrid - CanUserAddRows="True" not working

01.02.2025 - 13:58 Uhr

Eine Zahl mit 10 Millionen Stellen ist aber auch schon sehr groß.

Aber noch ein paar Verbesserungsvorschläge:
- Kannst du nicht direkt den BigInteger(byte[]) Konstruktor benutzen?
- Statt Division und Modulo getrennt zu berechnen, kannst du DivRem benutzen.

Edit:

Abt, du warst schneller! Aber genau so meinte ich den verbesserten Code (nur an das Reverse des Arrays wegen Little-Endian hatte ich nicht gedacht).

29.01.2025 - 09:53 Uhr

Den trinären Operator ?: kann man auch direkt bei der Zuweisung benutzen:

TabBatchImportDefinitionen.AsEnumerable().Select(row =>
{
     return new BatchImportDefinition
     {
          Bezeichnung = (string)row["BEZEICHNUNG"],
          ...
          ENCODING_TEXT = Convert.IsDBNull(row["ENCODING_TEXT"]) ? 0 : Convert.ToInt32(row["ENCODING_TEXT"], App.GebietsSchema) // DB-NULL Werte abfangen
      };
});

Persönlich hätte ich dann nur row["ENCODING_TEXT"]als Variable benutzt, damit es nur einmalig berechnet wird:

TabBatchImportDefinitionen.AsEnumerable().Select(row =>
{
     var encodingText = row["ENCODING_TEXT"];
     return new BatchImportDefinition
     {
          Bezeichnung = (string)row["BEZEICHNUNG"],
          ...
          ENCODING_TEXT = Convert.IsDBNull(encodingText) ? 0 : Convert.ToInt32(encodingText, App.GebietsSchema) // DB-NULL Werte abfangen
      };
});

Eigenartig finde ich nur, daß die Encoding-Spalte als Text (string) in der DataTable definiert ist (wenn du diese dann doch als Zahl interpretierst). Oder können dort auch Encodings wie  UTF8, UTF16stehen? Dann würdest du aber eine Exception erhalten...
Und auch die Angabe eines lokalisierten IFormatProviders bei so einer Spalte ist sehr eigenartig. Wäre CultureInfo.InvariantCulture dort nicht sinnvoller?

28.01.2025 - 10:14 Uhr

Benutze den Debugger ([Artikel] Debugger: Wie verwende ich den von Visual Studio?), setze passende Haltepunkte und überprüfe, welche Methoden ausgeführt werden.

Der Konstruktor sollte auf jeden Fall ausgeführt werden, nur wird evtl. das KeyDown-Ereignis vom Canvas nicht erkannt (dieses ist ja eine reine Zeichenfläche, kein Eingabeelement): erzeuge dieses Ereignis daher mal direkt für die Page.

25.01.2025 - 09:41 Uhr

Möchtest du eigentlich Base255 oder Base256 als Eingangsdaten?

PS: WW (als Base23) entspricht dezimal 22*23+22 = 528. Und das entspricht weder [2,11] in Base255 (= 521) noch in Base256 (= 523).

Edit:
Und auch dein bisheriger Umrechnungscode erscheint mir fehlerhaft (bes. die while-Schleife sowie das nirgendwo gesetzte carry!?). Schau mal in Horner-Schema: Umwandlung zwischen verschiedenen Zahlensystemen.

23.01.2025 - 16:17 Uhr

Hallo und willkommen,

ist das eines deiner ersten Projekte mit WPF? Und kennst bzw. verwendest du schon MVVM (s. [Artikel] MVVM und DataBinding)?

Ein gutes Beispiel mit MVVM für die Navigation zwischen verschiedenen Seiten ist Navigation mit WPF und MVVM. Als MVVM-Framework verwendet es MvvmLight Framework, aber du kannst auch ein anderes, wie das bekannte MVVM-Toolkit (als Teil des  .NET Community Toolkit) verwenden, s.a. Einführung in das MVVM-Toolkit (teilweise heißen die Klassen und Methoden dann dort anders).

Und bzgl.

Ich hab es mit einem Frame probiert, aber dann konnte ich meine Buttons nicht mehr betätigen.

Dazu solltest du uns den betreffenden Code zeigen.

20.01.2025 - 09:46 Uhr

Hallo und willkommen,

du solltest dazu geschrieben haben, daß es sich um C#-Code für Unity handelt.

Was mir auffällt:
Es wird bisher nirgendwo NextLevel() aufgerufen. Du mußt in der Update-Methode, genauso wie für die bisherige Button-Abfrage, den Button für "NextLevel" abfragen.

Ich bin jedoch kein Unity-Experte und weiß z.B. nicht, was genau gameObject dort bedeutet.

PS: Üblicherweise setzt man bei solchen Projekten endliche Zustandsautomaten (finite state machines) ein. Als Beispiel für Unity habe ich Simple Finite State Machine for Unity (C#) gefunden.

03.01.2025 - 10:28 Uhr

Und wenn die übergebenen Parameter xPos/ yPos die relative Position angeben sollen, dann noch die Werte dazuaddieren:

f3.Location = new Point(rect.X + xPos, rect.Y + yPos);
18.12.2024 - 18:08 Uhr

Schau dir die Fehlermeldungen an (und vom Visual Studio aus kannst du mit F1 direkt die Dokumentation im Browser aufrufen oder benutze [Hinweis] Syntaxfehler selbst lösen (Compilerfehlermeldungen)).

In C# müssen alle Methoden innerhalb einer Klasse (oder Struktur) liegen, es gibt keine freien Funktionen (wie z.B. in C oder C++).

09.12.2024 - 11:34 Uhr

Hallo,

mittels Main main = new Main()erstellt du eine neue (aber unsichtbare) Form-Klasse und beschreibst dessen TextBox. Du benötigst entweder eine Referenz auf die existierende Form oder aber noch besser, du verwendest ein Ereignis dafür: [FAQ] Eigenen Event definieren / Information zu Events (Ereignis/Ereignisse)

Ich habe hierfür auch extra einen Artikel geschrieben: Kommunikation von 2 Forms (gilt auch für Form-Klasse-Kommunikation)

04.12.2024 - 15:40 Uhr

Wie Abt geschrieben hat, verwende ein Event dafür, s. [FAQ] Eigenen Event definieren / Information zu Events (Ereignis/Ereignisse).

Und da der Aufruf aus einem Thread erfolgt, mußt du UI-Ausgaben synchronisieren: [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)

Du solltest, statt mit Threads zu arbeiten, dich auch mal über asynchrone Programmierung informieren: Task, await/ async.

02.12.2024 - 11:11 Uhr

Du solltest auch in HighlightTextBlock auf die Daten zugreifen und nicht auf die UI-Komponenten, also den Text aus der ItemsSource(bzw. DataSource) auslesen bzw. als Parameter übergeben.

Du solltest datenorientiert vorgehen, daher auch mein Vorschlag bzgl. UI-unabhängiger Highlighter-Klasse.

29.11.2024 - 18:01 Uhr

Der Umbau der Highlighter-Klasse ist nur ein Vorschlag von mir, wie ich es selber machen würde.

Du solltest den Code unterhalb von grid.LoadingRow += GridOnLoadingRow;

// Get DataGridRows
...

entfernen und entsprechend HighlightRow(e.Row) in die Ereignismethode GridOnLoadingRow packen, damit sich auch die Inlines-Texte aktualisieren.

PS: Du fügst bisher jedesmal mit grid.LoadingRow += GridOnLoadingRow;die Ereignismethode dem Ereignis hinzu (so daß er je Aufruf immer mehrfach ausgeführt wird) - dies sollte nur einmalig passieren!

29.11.2024 - 12:51 Uhr

Dein Highlighter funktioniert aber doch bisher auch nur für das DataGrid, da es explizit DataGridRow benutzt (welches bei TreeView nicht existiert).

Das Auslagern in ein ViewModel soll einfach dafür sorgen, daß die Logik eben UI-unabhängig ist. Du kannst die Funktionalität ja trotzdem in eine eigene Highlighter-Klasse auslagern, welche dann von den ViewModels benutzt wird.

Und diese Highlighter-Klasse sollte eben nur auf den Daten (Collection) operieren und ebenfalls nur Daten zurückliefern, welche dann von einem entsprechenden Control/Data-Template in UI-Komponenten aufgelöst wird, s. z.B. WPF ItemsControl Fundamentals - Part 1 (das Beispiel weiter unten mit dem CityViewModel und den Orten mit Flaggen).

Da TextBlock.Inlines jedoch kein DependencyObject ist, kann daran nicht gebunden werden. Evtl. hilft dir aber die Antwort bzgl. TextBlockExtensions aus Data binding the TextBlock.Inlines?

29.11.2024 - 11:36 Uhr

Für ein DataGrid benötigst du aber keine PanelVirtualisierung. Hast du ein StackPanel als äußeren Container?

Falls es dir um die vertikale Scrollbar bei dem DataGrid geht, dann s. How can I enable scrollbars on the WPF Datagrid?

Und wenn es dir um Virtualisierung für das DataGrid selbst geht (also um sehr viele Zeilen anzuzeigen, ohne alle im Speicher zu halten), dann s. DataGrid.EnableRowVirtualization (aber der Standardwert dafür ist schon true).

Und dies wird dann auch der Grund für dein Problem sein, da du auf die DataGrid.Row zugreifst, anstatt auf die Daten (d.h. über die ItemsSource).

M.E. wäre es auch besser, wenn du die ganze Highlighter-Logik über das ViewModel (das du übrigens aus deiner Window-Klasse auslagern solltest, s.a. [Artikel] MVVM und DataBinding) lösen solltest - und nicht direkt über die UI-Komponenten, sondern per Control Templates und Binding.

29.11.2024 - 09:34 Uhr

Hallo,

funktioniert es denn ohne VirtualizingPanel.IsVirtualizing = true?

Hast du denn mehrere virtuelle DataGrid-Elemente, daß du dies überhaupt benötigst (denn auf dem Screenshot kann ich das nicht sehen)?

PS:
Anstatt in der Filterfunktion mehrfach ToUpper()aufzurufen, ist es performanter direkt einen case-insensitiven Stringvergleich durchzuführen (s. String.Compare(String, String, StringComparison)):

String.Compare(item.Name, Filter, StringComparison.CurrentCultureIgnoreCase) == 0

(was du ja beim Highlighter bei IndexOf(...)auch schon nutzt ;- )

28.11.2024 - 12:43 Uhr

Direkt geht das nicht, da die jeweiligen Command-Zuweisungen (an KeyBinding und Button) ja unabhängig voneinander sind, d.h. es gibt keine Referenz zwischen beiden.

Du müßtest alles über das ViewModel lösen, d.h. Eigenschaften für Modifiers und Key dort angeben und dann für den Tooltip-Text auch noch.

21.11.2024 - 13:30 Uhr

Das WPF TabControl erzeugt beim Selektieren von einem TabItem immer dieses neu und verwirft das vorherige (daher ist nur noch das aktuell selektierte im VisualTree vorhanden), s.a. WPF TabControl: Turning Off Tab Virtualization.

Ansonsten müßtest du über alle Items iterieren und jeweils der Reihe nach diese selektieren, s.a. Iterate through TabItems in a TabControl:

tabControl.SelectedIndex = i;
UpdateLayout();

Nun sollte der VisualTree für das selektierte TabItem verfügbar sein.

20.11.2024 - 11:19 Uhr

Das bedeutet, daß auch deine Datenklasse public sein muß:

public class Datenklasse
{
  // ...
}

Alternativ könnte man auch beide auf internal setzen (welches der Standard bei Klassen ist, wenn man selber keinen Zugriffsmodifikator angibt) - dies wäre aber nur bei Libraries sinnvoll, um den Zugriff einzuschränken.

PS:
Warum heißt deine Methode getDatenklasse anstatt setDatenklasse(bzw. laut C# Styleguide besser SetDatenklasse)?

19.11.2024 - 20:59 Uhr

Hallo und willkommen,

was genau meinst du mit

Leider kann ich diese Methode nicht public machen, nur private.

?

Du brauchst nur das Schlüsselwort public vor die Methode schreiben (bzw. anstatt private).

Und bzgl.

Wie krieg ich denn diese Datenklasse als ref in die Form2?

Eine Klasse (im Gegensatz zu einer Struktur) wird automatisch als Referenz übergeben, d.h. bei z.B.

private MyData myData;

public void SetData(MyData data)
{
  myData = data;
}

beziehen sich alle Änderungen an den Eigenschaften von myData automatisch auch an den beim Aufruf übergebenen Parameter (aus der anderen Form-Klasse).

Üblicherweise würde man diese Referenz jedoch direkt im Konstruktor der Klasse übergeben (damit nicht noch extra eine weitere Methode bzw. Eigenschaft dafür aufgerufen werden muß):

public Form2(MyData data) // bzw. wie auch immer die Formklasse heißt
{
  myData = data;
}

PS:
Du kannst dir auch mal meinen Artikel zur "Kommunikation von 2 Forms" aus meiner Signatur dazu durchlesen.
Insb. wenn du die Form2als modalen Dialog mittels ShowDialog()aufrufst, kannst du den Code anders schreiben.

08.11.2024 - 11:46 Uhr

Laut OPC-Doku 5.13.2 CreateSubscription kannst du mal 0(oder einen negativen Wert) angeben, damit der Server das kürzeste Intervall benutzt (evtl. ist aber 1 Sekunde schon dieses?!).

08.11.2024 - 10:54 Uhr

Hast du diese Zeile entsprechend angepaßt

PublishingInterval = 1000, // Publish every second

?

07.11.2024 - 09:45 Uhr

Verwendest du das OPCFoundation/UA-.NETStandard SDK?
Dann schau dir das Code-Beispiel Applications/ConsoleReferenceClient/ClientSamples.cs (SubscribeToDataChanges) an - du benötigst also noch ein MonitoredItem, für das man dann das Notification-Event abonniert.

05.11.2024 - 12:18 Uhr

Dann sollten beide aber Eigenschaften sein:

public string Name => _name;
public int Amount => _amount;

Oder unterstützt Unity keine Eigenschaften?

Und ginge statt string nicht auch ein enum? Oder woher kommt bei getResource( string typ )der Parameter?

30.10.2024 - 07:57 Uhr

Und als weiterer Hinweis bzgl. "Events für UI-Infos" s. [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke).

Alternativ den kompletten Code auf asynchron (async/ await) umstellen.

PS:
Außerdem solltest du keine absoluten Pfade auf Windowsverzeichnisse direkt im Code benutzen, sondern dafür dann Environment.GetFolderPath benutzen.

21.10.2024 - 09:13 Uhr

Die übliche Lösung ist, einen eigenen Button-Style zu definieren, jedoch kannst du auch mal versuchen einfach einen TextBlock innerhalb des Buttons als Content zu setzen und dessen Hintergrundfarbe zu ändern, s.a. die Antworten in WPF Disabled button's background.

19.10.2024 - 12:50 Uhr

Ja, das ist äquivalent und seit C# 12 (.NET 8) verfügbar, s.a. Sammlungsausdrücke (auf engl. "collection expressions").

Der von deinem Kollegen verwendete Code Cleaner bezieht sich auf die Stilregel Auflistungsinitialisierer oder Sammlungsausdrücke verwenden (IDE0028).

Ich persönlich verwende aber immer noch die Form

ObservableCollection<MyType> list = new();

da ich dies intuitiver zu lesen finde.

PS: Du hättest besser ein eigenes Thema dafür erstellt.

15.10.2024 - 10:18 Uhr

Verwendest du evtl. irgendwo in deinem Code listview.Clear()anstatt listview.Items.Clear()(denn ersteres löscht auch alle Spalten)?