Laden...

Forenbeiträge von Alf Ator Ingesamt 764 Beiträge

30.08.2023 - 15:40 Uhr

Zitat von echdeneth

Demnach Normalisiert und ID (und Namen) abfragen und ne Runde switchcasen...

Ich habe das anders verstanden: Die Enum-Werte als int in der Tabelle speichern und (eventuell mit einer Converter-Klasse) im Programm passend umwandeln.

Zitat von echdeneth

Ob da mehr an Sicherheit reinkommt ist Chefsache...

Der Chef hat davon keine Ahnung. Deswegen ist es unsere Aufgabe als Entwickler ihm das klar zu machen. 😛

29.08.2023 - 10:16 Uhr

Zitat von rockxk

Da ich aber kein C++ Profi bin, komme ich nicht wirklich richtig weiter.

Sei nicht immer so sparsam mit deinen Infos. Woran hapert es denn genau? Was hast du gemacht?

28.08.2023 - 15:28 Uhr

Salut rockxk

Du könntest die Funktionalität in C# implementieren und eine Wrapper-DLL per C++/CLI bereitstellen:
https://learn.microsoft.com/de-de/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp?view=msvc-170

Gruss
Alf

03.08.2023 - 09:14 Uhr
[HttpGet]
       //public IEnumerable<VIEW_SWP_CYCLETIME> Get([FromForm] VIEW_SWP_CYCLETIME value)
       public IEnumerable<VIEW_SWP_CYCLETIME> Get(int lineID, int machineID)
       {
           return _currentRepository.Data.Where(item =>
                    (machineID > 0 || item.MACHINE_ID == machineID)
                   && (lineID > 0 || item.LINE_ID == lineID)
               ); 
       }

Hallo Bronstein

Wofür ist denn 'machineID > 0' und warum ist das 'verodert'?

Gruss
Alf

28.07.2023 - 09:29 Uhr

Zitat von perlfred

Im Prinziep möchte ich, dass Als erstes data1 abgerufen wird, danach data2 oder data3 und am Schluß Vorgang1 ausgeführt wird.

Task hat doch sowas wie .ContinueWith(). Schau dir das mal an.

26.07.2023 - 08:10 Uhr

Hallo cprogrammer

Zitat von cprogrammer

//Unklar
var positive = deltaInfos.Where(h => h.Delta > 0).Average(h => h.Delta);
var negative = deltaInfos.Where(h => h.Delta < 0).Average(h => h.Delta);
var ControlPositive = deltaInfos.Where(h => h.Delta > positive * Multiplier).ToList();
var ControlNegative = deltaInfos.Where(h => h.Delta > negative * Multiplier).ToList();

.Where und .Average sind Linq-Methoden.
Das mit dem ⇒ ist ein Lambda-Statement.

Mit diesen Stichworten solltest du alles Nötige finden.

Zitat von cprogrammer

Aber der Abschnitt hier lautet ja "Grundlagen c#", weshalb ist es dann anrüchig Grundlagenfragen zu stellen ?

Du kannst hier gerne solche Fragen stellen, und du bekommst ja auch die Antworten. Aber eben auch diejenigen, die du nicht hören willst. Und auch wenn Abt manchmal etwas harsch ist, würde ich mir seine Worte zu Herzen nehmen.

Viele Grüße
Alf

24.04.2023 - 15:21 Uhr

Hallo perlfred

Als was liegt denn die Geometry vor?
Ist das ein PathGeometry oder mehrere zusammengesetzte Pfade?

Gruss
Alf

19.04.2023 - 13:48 Uhr

Du hast das SelectedIndexChanged-Event nicht registriert. Siehe Bild.
Da frage ich mich aber, wie du mit dem Debugger in den Event-Handler lbDSGVO_SelectedIndexChanged reinlaufen konntest.

18.04.2023 - 10:55 Uhr

Imho sollte Bezeichnung der Bedingung mit einbezogen werden. Optimalerweise ist diese aussagekräfig genug um auf '== true' verzichten zu können. Also sollte eher der Name der Bedingung angepasst werden, statt '== true' zu verwenden.

if (prime.IsGreaterThan(100))

if (dictionary.TryGetValue(path, out path))

if (File.Exists(path))

Bei der negativen Bedingung kann die verwenden von 'is false' sinnvoll sein. Man sieht es besser als ein '!'. Ich finde die Schreibweise 'is false' besser als '== false' (siehe Herbivores Beitrag).

Ich gehe also mit Abt: 'is false' kann die Lesbarkeit erhöhen, '== true' nicht.

18.04.2023 - 09:52 Uhr

Also ist schonmal sichergestellt, dass die Methode 'LbDSGVO_SelectedIndexChanged' überhaupt aufgerufen wird.

Durch den Code hier, sollte sichergestellt sein, dass die Datei existiert.

            // Check if the file exists
            if (!File.Exists(filePath))
            {
                MessageBox.Show("File not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

Wie ist denn der Wert von filePath? Existiert diese Datei tatsächlich, und ist der Inhalt korrekt?

Wenn du mit dem Debugger durchsteppst, kommst du zu dieser Zeile? Was passiert danach?

rtbDatei.LoadFile(filePath, RichTextBoxStreamType.RichText);
17.04.2023 - 18:27 Uhr

Hallo Runenmeister

Häng dich mal mit dem Debugger in die MethodelbDSGVO_SelectedIndexChangedrein und steppe da durch.

[Artikel] Debugger: Wie verwende ich den von Visual Studio?

Gruss
Alf

06.04.2023 - 09:10 Uhr

Hallo sacoma

Weil ich länger nichts mehr mit WPF gemacht habe, habe ich mir das Thema mal als Fingerübung genommen und Cavemans Ansatz weiterverfolgt.

Für die tabellenartige Darstellung ist nicht primär das ItemsControl relevant, sondern die Eigenschaft ItemsPanel. Die gibt es auch am ListView. Der Unterschied zwischen ItemsControl und ListView ist im wesentlichen das Selections-Verhalten.

Back to topic: Ich habe ein View für die Hochregale erstellt und eines für die Lagerplätze.

Lagerplatz aka RegalFach: der Status ist ein Enum und wird mit dem Converter in eine Farbe umgewandelt.

    <UserControl.Resources>
        <local:RegalFachStatusToBrushConverter x:Key="regalFachConverter"/>
    </UserControl.Resources>
    
    <ItemsControl ItemsSource="{Binding AllRegalFach}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border BorderThickness="2" BorderBrush="{Binding Status, Converter={StaticResource regalFachConverter}}">
                    <TextBlock Text="{Binding Id}" />
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

HochregalViewModel hat eine ObservableCollection, die kann die UI über Änderungen benachrichtigen.

    public class HochregalViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<RegalFachViewModel> AllRegalFach { get; }

        public HochregalViewModel(IList<RegalFachViewModel> allRegalFach)
        {
            AllRegalFach = new ObservableCollection<RegalFachViewModel>(allRegalFach);
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string? name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }

Mehrere Hochregale mit der ItemsPanel-Eigenschaft nebeneinander stellen:

    <ItemsControl ItemsSource="{Binding AllHochRegal}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <local:HochregalView />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" VerticalAlignment="Top" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

Damit solltest du schonmal was anfangen können. Den Rest kann man sich zusammenreimen.

Wichtig ist die Aufteilung zwischen ViewModel und Model. Das RegalFachViewModel (er)hält die Daten vom RegalFach. RegalFach kommt aus dem Repository, dass den Datenbank-Zugriff kapselt. MVVM ist eine Technik für die UI. Les dir dazu nochmal den von FZelle verlinkten Artikel durch und am Besten auch https://mycsharp.de/forum/threads/111860/artikel-drei-schichten-architektur.

Gruß
Alf

03.04.2023 - 09:12 Uhr

Hallo echdeneth

Ich verstehe deine Frage nicht.

Eventuell könntest du dein Binding auf SelectedItem noch mit UpdateSourceTrigger=PropertyChanged ausstattest.

Gruss
Alf

15.03.2023 - 17:19 Uhr

Ich glaube deine Action-Properties müssen noch mit der UI über Änderungen kommunizieren.
Das heisst INotifyPropertyChanged für Action implementieren, oder ObservableObject.
Kann sein, dass du aus dem record dann ein class machen musst. Weiss ich nicht genau.


public record Action() : ObservableObject, IAction
{
    [ObservableProperty]
    public string Id { get; set; } = Constants.NotAvailable;

    [ObservableProperty]
    public long Timestamp { get; set; } = 0L;

    [ObservableProperty]
    public string Value { get; set; } = Constants.NotAvailable;
}

Gruss
Alf

15.03.2023 - 16:44 Uhr

Ja, die Diskussion ist etwas ausgeartet. 😁
Für deinen Anwendungsfall hast du ja eine gute Lösung gefunden. 👍

Mir ging es in erster Linie darum, dass niemand diesen Thread liest und dann denkt er könnte mit SecureString seine Kundendaten sichern.

Auch hier wieder die Frage, was ist konkret die bessere Alternative?

Ich kann meine Empfehlung nur nochmal wiederholen, für Security etablierte Systeme zu benutzen. Das kommt natürlich drauf an, wie der UseCase ist. In einer Windows-Domain würde man also ActiveDirectory verwenden, im Web einen passenden Anbieter.

Viele Grüsse

15.03.2023 - 15:30 Uhr

Hallo kelo

Wo genau hängt es?
Gibt es eine Fehlerausgabe im Output?
Wie sieht denn der

MyDataTemplateSelector

aus?

Gruss Alf

15.03.2023 - 14:17 Uhr

Die Obscurity ist in dem Fall, dass das Passwort nur kurz im Speicher gehalten wird. Wenn man das weiss, dann kann man seinen Angriff entsprechende danach ausrichten.

Das SecureString sicherer ist, als String, bestreite ich gar nicht. Mein Kritikpunkt geht eher dahin, den Passwort-Dialog selber zu erstellen, ergo Security selber zu machen. Das mag für deinen Anwendungsfall okay sein. In der Praxis sehe ich aber immer wieder, dass Firmen versuchen auf diese Weise Kundendaten zu schützen. Adressdaten, Bank-Verbindungen, Patientenakten. So ein Security-Vorfall, kann auch locker einer grösseren Firma den Kopf kosten, von den geschädigten Personen ganz zu schweigen.

Ich kann meine Empfehlung nur nochmal wiederholen, für Security etablierte Systeme zu benutzen. Das kommt natürlich drauf an, wie der UseCase ist. In einer Windows-Domain würde man also ActiveDirectory verwenden, im Web einen passenden Anbieter.

15.03.2023 - 09:55 Uhr

Im Endeffekt ist das eine "security through obscurity"-Diskussion. Ich denke die Argumente für und wieder sind im Netzt zur genüge ausgetauscht.
Ich für meinen Teil kann nur empfehlen bei Security-Themen immer auf etablierte Systeme zu gehen und sowas nicht selber zu machen. 😉

14.03.2023 - 09:48 Uhr

Hier eventuell Hilfreich:
[Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden

Siehe auch die Links unten in dem Artikel.

09.03.2023 - 08:44 Uhr

Hallo C4RL0

Im Moment ist es eine Mini-Forms-Anwendung, in welcher ich mit dem Thema Webservices etwas herumspiele, ..
Bevor ich mich an die richtige Anwendung mache, bzw. es dort implementiere, möchte ich mir bei diesem Thema sicher sein.

Erstellst du den WebService selber? Überleg dir mal, ob du statt WCF/SOAP auch REST verwenden kannst.

Gruß
Alf

08.03.2023 - 08:43 Uhr

Hallo Rustasian

Die Kollegen, die die Software programmieren, können beim Compilieren eine DLL für .NET compilieren, ...

Einfach in deinem Projekt eine Referenz auf die DLL einfügen.

Kannst du den Quellcode der DLL anschauen?

Gruß
Alf

22.02.2023 - 13:50 Uhr

Hallo Florena

Keep cool. Abt ist zwar streng, aber er hat (in aller Regel) recht.

Schau dir mal diesen Link an: c-sharp-settings-default-save-not-saving
Vielleicht hilft dir das weiter.

Gruss
Alf

09.02.2023 - 09:28 Uhr

Hallo Sisco86


MainWindow.label01.text = "Hallo";

Das was du da machst, ist auch in VB keine gute Idee. Die Geschäfts-Logik sollte keine Abhängigkeit auf die UI haben:

[Artikel] Drei-Schichten-Architektur

Gruß
Alf 🙂

08.02.2023 - 10:05 Uhr

Hallo stony17

Wie könnte ich sowas in mehreren Stufen umsetzen.
Am Ende möchte ich die gesamte Logik auf einen Server haben bzw. mehreren Serven (Ausfallsicherheit).

Welche Technologien sollte man dafür verwenden.

Für die Kommunikation mit der Server-Anwendung kannst du Beispielsweise sowas verwenden: https://github.com/grpc/grpc
Oder du setzt einen REST-Server auf. Das halte ich aber für komplexer. Unter anderem wegen der Sicherheitsaspekte.

Die gesamte Logik auf dem Server zu haben macht nicht zwangsläufig Sinn. Entscheide lieber, welche Logik wohin passt.

Auch habe ich das Problem bei Programmänderungen, das ich jeden PC nachrennen muss.
Updaten kann man nur wenn keine Produktion stattfinden, da das Programm ständig Daten nach Navision übertragen muss. Sprich in der Pause der Produktion oder nach Schichtende.

Für die Update-Funktionialität gibt es auch fertige Pakete, beispielsweise: https://github.com/ravibpatel/AutoUpdater.NET

Eventuell macht es auch Sinn, einen Windows-Service einzurichten, der sicherstellt, dass die Anwendung läuft und aktuell ist. Das hängt aber von den Umständen ab.

Ausfallsicherheit ist wieder ein eigenes Thema. Da könntest du dich mit Docker beschäftigen und wie man den Server per Script deployed, bzw, neu aufsetzt. Da kann man aber beliebig viel Zeit investieren.

Gruß
Alf

31.01.2023 - 14:59 Uhr

Hallo vkry

Die Gelegenheit möchte in nutzen und einen besonders wichtigen Punkt hervorheben und ergänzen:

Kontinuierlich
Einige Verbesserungen kann man manuell bereits während der Codierung umsetzen. Es gilt das Prinzip: Wenn man Änderungen an einer Stelle des Quellcodes vornimmt, dann sollte man diesen sauberer verlassen, als man diesen vorgefunden hat.

Bei der täglichen Arbeit steht der Entwickler für gewöhnlich unter einem gewissen Zeitdruck. Für explizite Refactorings bekommt er nicht immer Zeit. Deswegen ist es wichtig, kontinuierlich sauberen Code zu entwickeln. Dafür muss klar definiert sein, wie der Code strukturiert sein soll und die Architektur aussieht.

Im Entwickler-Team sollten also unter anderem folgende Punkte geklärt sein:

  • UnitTests:
  • wo kommen die hin
  • in welchen Fällen kann darauf verzichtet werden
  • wird TDD gemacht.
  • Schichten:
  • welche gibt es: Domain, DB, UI, ..
  • welche Schicht, hat wo Zugriff
  • technische oder fachliche Aufteilung von Code
  • wann und wie wird die Architektur angepasst

Die Liste ist natürlich nicht vollständig. Meiner Erfahrung nach, ist das oft nicht ausreichend geklärt. Meiner Meinung nach ist es aber essentiell, für sauberen Code.

Gruss
Alf

Das Prinzip wird übrigens auch Pfadfinder-Prinzip genannt.

Arbeitest du für Visual Assist?

31.01.2023 - 14:12 Uhr

Hallo stony007_de

Bei dem Code, den du dir zusammenkopiert hast, steht sowas:


//encryptor.Padding = PaddingMode.Zeros;

Kannst ja mal damit rumspielen.

Gruss
Alf

04.01.2023 - 16:57 Uhr

Hallo Gruwe

Das wichtigste ist ja schon gesagt worden. Ich wollte noch ergänzen, dass es auch stark darauf ankommt, was für ein Produkt man entwickelt.
Eine Enterprise-Solution mit 10Millionen Zeilen Code wird anders aufgebaut, als ein Kommandozeilen-Tool.

Diverse Patterns oder [Artikel] Drei-Schichten-Architektur machen bei einem kleinen Beispiel-Projekt nicht direkt Sinn. Sollte die Anwendung aber wachsen, dann wird es ohne schnell unübersichtlich.

Gruss
Alf

13.12.2022 - 16:38 Uhr

Damit ist meine Frage wohl ausreichend beantwortet. Vielen Dank!

12.12.2022 - 19:50 Uhr

Na so in etwa:


internal class Kunde
{
    public string Name { get; set; }
}

internal class Produkt
{
    public string Nummer { get; set; }
}

internal class Order
{
    public Kunde Kunde { get; set; }
    public Produkt Produkt { get; set; }
}


// und für die ausgabe
(readonly) textbox_ordernr = myorder.ordernr //  Ihre Bestellung NR. 123456 ( wird von system erstellt)

Für das readonly kannst du den Setter privat machen.


// ausgabe des Gesammten Kunden
myorder.Kunde() // Rückgabe "Hans Schmidt"

Hier kannst du eine entsprechende Methode Kunde() implementieren, oder ToString() überschreiben.

12.12.2022 - 18:16 Uhr

Hallo Commander82

Du kannst jeweils eine Klasse Kunde und Product erstellen, mit den jeweiligen Properties.

In Order bietest du dann eine Property mit Kunde/Product an.

Gruß
Alf

12.12.2022 - 17:30 Uhr

Hallo Zusammen

Ich habe das Zyan Communication Framework gerne benutzt. Gibt es etwas ähnliches für .NET Core? Was benutzt ihr so für die Kommunikation im LAN, oder zwischen Prozessen??

Danke für eure Kommentare und winterliche Grüße
Alf

28.11.2022 - 17:23 Uhr

Hallo kstanger


        private void DataGridViewTiming_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            for (int loop = 0; loop < Timings.Count; loop++)
            {
                ...
                DataGridViewTiming.DataSource = BindingSourceTiming;
            }
        }

Das hier kommt mir ein bisschen fishy vor. Wenn das DataBinding complete ist, weist du eine neue DataSource zu? Und das auch noch mehrfach?
Ich könnte mir vorstellen, dass er hier viel zu oft reinrennt. Kannst du das mal mit dem Debugger testen?

Gruß
Alf

28.11.2022 - 17:18 Uhr

Hallo BlueSubmarine

Hier kannst du dir das anschauen:
Standard-Toolkit/KryptonStatusStrip.cs at master · Krypton-Suite/Standard-Toolkit

Andere Controls leiten von irgendwelchen Basis-Klassen ab, z.B. VisualForm, oder VisualControlBase. Das fehlt beim KryptonStatusStrip, deswegen vermute ich, dass es die Palette einfach nicht unterstützt.

Wenn du es dringend brauchst, kannst du dich ja auch mal direkt an die Macher wenden.

Gruß
Alf

28.11.2022 - 10:38 Uhr

Hallo AlphaNumerisch0815

Dein Text ist nicht ganz einfach zu verstehen und es sind viele Fragen drin, dich ich nicht einzeln beanworten will.

Grundsätzlich kann man sagen, dass man als Entwickler Spaß daran hat, Probleme zu Lösen. Die Informationen dazu holt er sich auf den verfügbaren Wegen. Als es noch kein Internet gab, waren das z. B. Bücher (aus Papier 😛). Dabei lernt der Entwickler bestimmte Patterns und Best Practices kennen und anzuwenden. Mit steigender Erfahrung bekommt der Entwickler ein Gefühl für sauberen Code und guten Programmaufbau.

Für den Angfang schau hier rein: [FAQ] Wie finde ich den Einstieg in C#?
Dann suchst du dir ein interessantes Problem und ran an den Speck. 🙂

Gruß
Alf

21.11.2022 - 10:19 Uhr

Hallo Kjell

Erstmal wäre es sinnvoll dein Problem auf das wesentliche zu reduzieren:
(Ich habe bei dem Beispiel mal List<T> genommen, statt string-Arrays)


        static void Main(string[] args)
        {
            var list1 = new List<string>
            {
                "Software 1",
                "Software 2",
                "Software 3"
            };

            var list2 = new List<string>
            {
                "Software 1",
                "Software 3"
            };

            var differences = GetDifferences(list1, list2);

            Console.ReadKey();
        }
            
        private IEnumerable<string> GetDifferences(List<string> list1, List<string> list2)
        {
            // hier Listen vergleichen
            return new List<string>();
        }

Das ganze könntest du auch ganz hervorragend mit UnitTests machen:
C# unit test tutorial - Visual Studio (Windows)

Zum Listenvergleich kannst du Linq verwenden:
Language-Integrated Query (LINQ) (C#)

Es ist aber auch eine gute Übung, so einen Listenvergleich händisch umzusetzten. Wenn deine UnitTests funktionieren kannst du das gut machen und deine eigene Implementierung damit testen.

Zum Arbeiten mit csv-Dateien empfehle ich eine vorhandene Lösung zu verwenden, zum Beispiel:
https://www.nuget.org/packages/CsvHelper/

Beim programmieren gilt: aller Anfang ist schwer. Man muss viel Lesen, ausprobieren und verstehen. Aber immer wenn man dann einen Schritt weiterkommt und etwas verstanden und gelernt hat, macht es riesenspaß.

Viele Grüße
Alf

21.11.2022 - 09:58 Uhr

Ich wollte das mit einer Linq-Abfrage lösen, aber folgender Code funktioniert nicht:

Was funktioniert denn nicht?

16.11.2022 - 13:13 Uhr

Eine passende Lösung habe ich ja schon beschrieben, hat das funktioniert? 🙂

16.11.2022 - 08:50 Uhr

Hallo Webwiesel1212

Du kannst eventuell vom NumericVarOut-Control den Setter von Value überschreiben, oder es das Control bietet sowas wie ValueChangedEvent an.
Kann ich von hier aus jetzt nicht sehen.

Ansonsten kannst du zusätzlich im Setter von FactoryFloat die Berechnung auslösen oder machen.


public Double FactorFloat
{
    get { return (Double)GetValue(FactorPropertyFloat); }
    set
    {
        SetValue(FactorPropertyFloat, value); }
        this.Value = this.Value * FactorFloat;
    }

Gruß
Alf

14.11.2022 - 18:57 Uhr

Hallo kstanger

Deine Aufgabenstellung ist nicht richtig gut erklärt, dass könnte noch klarer werden. Eventuell auch mit etwas Code. Les das mal als jemand, der deinen Code nicht kennt.

Zum Problem:
Die Liste mit Objekten in deinem ViewModel, an die die ComboBoxen gebunden sind, könnten jeweils Objekte1 oder Objekte2 zurückgeben, in Abhängigkeit von Property in dem List1 oder Liste2 eingestellt ist.

Gruß
Alf

13.11.2022 - 11:09 Uhr

Hallo MMCSharp

So ganz verstanden habe ich das nicht, wie es bei dir aussieht. Ohne Code kann man da nur raten.

Prinzipiell würde ich sagen, dass du dafür einen IValueConverter verwendest: Wertumwandlung mit IValueConverter - The complete WPF tutorial

Gruß
Alf

13.11.2022 - 10:01 Uhr

Hallo liebe Forenten

Heute habe ich ein Problem, bei dem ich nicht weiterkomme. Folgende Situation:

Ich habe ein UserControl mit einem DependencyProperty im CodeBehind:


<UserControl
    DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <TextBox Text="{Binding WatermarkText}" />

</UserControl>


        public static readonly DependencyProperty WatermarkTextProperty = DependencyProperty.Register(nameof(WatermarkText), typeof(string), typeof(ValueSpinner), new PropertyMetadata("dp_default"));
        public string WatermarkText
        {
            get => (string)GetValue(WatermarkTextProperty);
            set => SetValue(WatermarkTextProperty, value);
        }

Im MainWindow ist im CodeBehind ein Property:


        private string _testText = "MainWindow_CodeBehind";
        public string TestText
        {
            get => _testText;
            set => SetField(ref _testText, value);
        }

Das binde ich nun auf das DependencyProperty vom UserControl:


<Window
    DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <StackPanel>
        <TextBox Margin="10" Text="{Binding TestText}" />
        <local:ValueSpinner Margin="10" WatermarkText="MainWindow_Xaml" />
        <local:ValueSpinner Margin="10" WatermarkText="{Binding TestText}" />
        <local:ValueSpinner Margin="10" WatermarkText="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=TestText}" />
    </StackPanel>

</Window>

Ergebnis sieht so aus:

Man kann sehen, dass bei der Zeile


<local:ValueSpinner Margin="10" WatermarkText="{Binding TestText}" />

das Binding nicht greift und ich verstehe nicht warum.

Edit: Setter und Callback vom DependencyProperty werden hier übrigens nicht aufgerufen.

Kann mir jemand erklären, warum das nicht tut, wie ich das will?

Viele Grüße
Alf

PS:
Das hier tut interessanterweise:


        <local:ValueSpinner Margin="10" WatermarkText="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=TestText}" />

Auf diese Idee kam ich dank Binding an einen DataContext von einem DataGrid das an eine ItemsSource gebunden ist

Edit2:
Ich verstehe jetzt, warum das Property nicht gebunden wird. Ich setze den DataContext vom ValueSpinner. Der DataContext von der Instanz von ValueSpinner wird deswegen anscheinend nicht geerbt.
Jetzt muss ich nur noch überlegen, wie ich dann mein ValueSpinner-View auf mein CodeBehind (oder ViewModel) binden kann.

Edit3:
Das ist tatsächlich die Lösung. DataContext vom UserControl nicht setzen und dafür beim bindenden Control direkt.


<UserControl>
    <TextBox Text="{Binding WatermarkText}" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ValueSpinner}}}" />
</UserControl>

Ich danke euch für eure Aufmerksamkeit. Für ergänzenden Anmerkungen bin ich dankbar.

Viele Grüße
Alf

26.10.2022 - 09:00 Uhr

Hallo Maendler53


 internal static void CellsMerge(string address)
        {
            string[] splited = address.Split(Convert.ToChar(":"));
            int firstCol;
            int firstRow = Cvr.GetIndexes(splited[0], out firstCol);
            int lastCol;
            int lastRow = Cvr.GetIndexes(splited[1], out lastCol);

            var von = Ws.CurrentSheet.Cells[firstRow, firstCol];
            var bis = Ws.CurrentSheet.Cells[lastRow, lastCol];

            Exc.Range rng = Ws.CurrentSheet.Range[von, bis] as Exc.Range; // Beim erstellen des Rangeobjekt, entsteht der Fehler.  Die Felder firstCol, firstRow, lastCol und lastRow sind  entsprechend Excel 1 basiert und richtig initialisiert.
            rng.Merge(Type.Missing);
        }

Mach das doch mal so, geh mit dem Debugger rein und schau dir an, ob die Exception bei 'von', oder bei 'bis' geworfen wird.

Gruß
Alf

22.09.2022 - 13:20 Uhr

Hallo prokrammer

Dann noch ein Hinweis: Ich hatte vesucht bei mir am Rechner den Bereich als Netzlaufwerk zu verbinden, mit den Userdaten des lokalen Users, das hat auch nicht funktioniert.
Fällt euch dazu noch etwas anderes ein, an was es scheitern könnte ??

Ich hatte damals, einen Service im Netz laufen lassen, an den die Maschinen ihre Daten senden konnten.

Gruß
Alf

22.09.2022 - 11:03 Uhr

Hallo kstanger

Das liegt daran, dass du Presettings im Scope der if-Abfrage definierst.

Der Scope geht von der { bis zur } der if-Abfrage. Alles was innerhalb definiert wird, ist ausserhalb nicht verfügbar.

Mach das mal so:


Presetting[] presettings;
if (..)
{
  ..
  presettings = JsonSerializer.Deserialize<Presetting[]>(jsonString);
  ..

Gruß Alf

PS: Les mal das: C# Coding Conventions

22.09.2022 - 10:54 Uhr

Hallo kstanger

numericUpDown war mir wohl bekannt, aber ich wollte die Auf- und Ab-Pfeile nicht.
Andererseits ist es besser, eine einfache (= NumericUpDown) Lösung zu nehmen.

Da sind ein paar Lösungen dabei:

Google Suche nach "c# numericupdown remove arrows"

Gruß
Alf

22.09.2022 - 10:44 Uhr

Hallo kingflo

Als erstes habe ich vermutet, dass das XML nicht valide ist. Das habe ich mit folgendem Tool überprüft:

https://community.notepad-plus-plus.org/topic/16983/xml-tools

Das XML ist aber valide, dass heißt der Fehler wird eher im Code zu finden sein. Der ist aber in deinem Beitrag nicht zu sehen. Du kannst ja mal posten, was du gemacht hast und was du versucht hast, um diesen Fehler zu beheben.

Les dir bitte auch diesen Beitrag durch: [Hinweis] Wie poste ich richtig?

Gruß
Alf

12.09.2022 - 10:13 Uhr

Problem ist gelöst 🙂

👍

Das mit dem UpdateSourceTrigger ist ja interessant. Hatte ja seine Berechtigung.
Mode=TwoWay ist imho der Default-Wert.

06.09.2022 - 10:26 Uhr

Hallo Toube

Das sieht eigentlich ganz gut aus. Hast du eine Lösung gefunden?

Wenn nicht, vielleicht probierst du mal bei dem Picker sowas:


SelectedItem="{Binding Parent, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"

Gruß
Alf

30.07.2022 - 11:27 Uhr

If(printDocument1.Print)
...[/csharp]

allerdings bringt es einen Fehler gleich in der ersten Zeile
Can not convert method group print in bool

Du hast die Klammern vergessen.