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 ;-)
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...
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.
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.
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.
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?
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.
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?
Deine Namen sind aber auch m.E. ein bißchen zu komplex - als VM-Eigenschaft würde ich es einfach IsArea1Active
bzw. IsArea1Checked
nennen (weder das Bind
noch der Control-Type ChBox
sind hier sinnvoll).
Du könntest ein Flag benutzen, s. [FAQ] Event nur bei Benutzeraktion auslösen, nicht bei programmtechnischer Änderung.
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
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.
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.
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...
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).
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 Team1
und 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)!
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.
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.
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).
Dafür gibt es extra den Forenbereich Code-Reviews (beachte aber dessen Regeln).
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).
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 0
setzen 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)?
Die zu bindende Klasse muß einen parameterlosen Konstruktor besitzen: Editable DataGrid - CanUserAddRows="True" not working
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).
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
, UTF16
stehen? 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?
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
.
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.
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.
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.
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);
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++).
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)
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
.
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.
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!
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?
Für ein DataGrid
benötigst du aber keine Panel
Virtualisierung. 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.
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 ;- )
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.
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.
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
)?
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 Form2
als modalen Dialog mittels ShowDialog()
aufrufst, kannst du den Code anders schreiben.
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?!).
Hast du diese Zeile entsprechend angepaßt
PublishingInterval = 1000, // Publish every second
?
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.
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?
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.
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.
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.
Verwendest du evtl. irgendwo in deinem Code listview.Clear()
anstatt listview.Items.Clear()
(denn ersteres löscht auch alle Spalten)?