Laden...
S
Sindelfinger myCSharp.de - Member
Automatisierer, Feierabendreporter Deutschland Dabei seit 05.08.2019 39 Beiträge
Benutzerbeschreibung
Über 20 Jahre Industrieroboter programmiert. C# ist cool - aber in manchen Dingen seeeeeeehr unterschiedlich. Genau mein Ding für eine Herausforderung

Forenbeiträge von Sindelfinger Ingesamt 39 Beiträge

26.09.2023 - 15:23 Uhr

Zitat von Abt

"dürfen". Es heisst "dürfen". "müssen" würde ausdrücken, was wäre was schlechtes 😉

Warum gibt's hier eigentlich immer noch keinen "Like" Button? 😉

24.02.2023 - 08:15 Uhr

Hallo Freunde!

Ich habe ja geschrieben, dass es nicht eilt, also bin ich erst jetzt dazu gekommen, mich dieser Kuriosität weiter zu widmen.

Wirf doch mal so lange Inhalte raus, bis Du einen deutlichen Größenunterschied sehen kannst.

Habe ich andersrum gemacht: Ein leeres Projekt erstellt und nach und nach die Inhalte eingefügt. Sehr verwundert hat mich die Tatsache, dass nichts fehlte und die exe dann plötzlich doch nur knappe 500k hatte. Wird wohl ein miraculum bleiben, aber stört ja nicht weiter.

Korrekt. Deswegen hab ich extra auch von "aktuell" gesprochen, nicht von "Steinzeit". 😉

Nicht ganz Steinzeit. Nur eben alte Geräte.

Die maximale Größe eine Exe-Datei unter Windows kann aktuell 4 GB betragen.

Da stand mir dann doch kurz die Klappe offen. Darauf war ich nicht vorbereitet. Ich erinnere mich noch an meine erste Festplatte. Die hatte 10MB, kostete fast 1000 Mark und wog über 1 kg. Da hat man sich früh daran gewöhnt, mit den vorhandenen Ressourcen sparsam umzugehen. Rechne mal hoch, wie schwer die Festplatte mit der damaligen Packungsdichte wäre, wenn dort in 4GB - Programm laufen müsste. Ganz zu schweigen vom Arbeitsspeicher (damals Erweiterung von 4 auf 8 MB schlappe 500 DM).

Für die Jüngeren: DM war die "Deutsche Mark". Damit hat man in der "Steinzeit" bezahlt 😉

Die Self - Contained Geschichte gefällt mir. Eignet sich sehr gut für ältere Geräte im Inselbetrieb.

23.01.2023 - 16:41 Uhr

Hallöchen Palladin.

Zunächst einmal Dankeschön für Deine schnelle Antwort.

Ich habe nur ganz wenige, kleine Resourcen eingebettet. Das sind ein paar Icons und ein paar Fonts - das war's.

Ich hab gerade eine WPF Anwendung mit 4.8 und Microsoft.Xaml.Behaviors, Prism.WPF und Prism Core erstellt, sonst nichts.
Der Debug-Build ist unter 2 MB groß.

Auch ich hab grad mal ein solches Projekt erstellt. Da ist die exe grad mal süße 8K "groß".

Und Du solltest auf das neue .NET umsteigen - macht vieles deutlich einfacher.
Z.B. ist die csproj-Datei deutlich übersichtlicher.

Das hat einen bestimmten Grund: Die Geräte auf denen das Progrämmchen laufen soll, sind meistens sehr alt und meistens nicht mit dem Internet verbunden. Mein kleines Testgerät hier wollte die - zum Glück testhalber schnell erstellte - .net Anwendung nicht starten. Deswegen bin ich zähneknirschend auf Framework 4.8 zurück. Da läuft das Vorgängermodel meines Programmes wunderbar drauf.

23.01.2023 - 15:01 Uhr

Liebe Forenmitglieder,

ich programmiere mir gerade eine lustige kleine Applikation. Mir fällt unangenehm auf, daß die .exe - Datei, die mir Visual Studio da erstellt, mit ihren knapp über 12 MB doch etwas groß erscheint.

Mein vorheriges Projekt war ein sehr mächtiges Tool mit sehr vielen Features und schlappen 40.000 Zeilen mehr Code. Die Exe - Datei von diesem Projekt ist schlanke 435 K groß.

Die einzigen (so far) Verweise sind auf die Microsoft.Xaml.Behaviors und die Prism.WPF und Prism Core. Das ist denke ich mal nicht der Grund dafür. Ich habe die Projekteigenschaften dieser beiden Projekten verglichen, aber keinen Unterschied feststellen können.

Noch kurz zu den Eckdaten:

Ich verwende VS2022, das Zielframework ist das .NET Framework 4.8

Hat jemand eine Idee?

Eilt aber nicht.

23.01.2023 - 14:27 Uhr

Ich habe schon im Internet recherchiert, aber noch nichts gefunden... 😠

Als ich mit WPF angefangen habe, war mein größtes Problem, die richtigen Suchbegriffe auszuwählen. Aber das kommt mit der Zeit.

Die Vorgehensweise mit dem ViewModel eröffnet Dir ungeahnte Möglichkeiten. Momentan fluchst Du wahrscheinlich noch mehr als Du tippst (so war's bei mir). Aber in 3 Monaten wirst Du es lieben. 😉

12.12.2022 - 16:42 Uhr

Gude TH69,

ich habe den DataContext des Usercontrols auf "Self" gesetzt (darüber bin ich auch schon gestolpert)

Nach einigem hin- und hertesten, lesen, lernen und verstehen, hab ich's jetzt hingekriegt. Dazu ein kleines Testprojekt gebaut. Folgendermaßen sieht das jetzt aus:


<UserControl x:Class="_090_UserControlZeuch.LabeledSlider"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:_090_UserControlZeuch"
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="400"
            DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid HorizontalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="6*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>

        <Label Content="{Binding SliderLabel}" Foreground="Black"
                   Grid.Column="0" FontSize="25"
               FontWeight="Bold"
               HorizontalAlignment="Left"/>
        <Slider x:Name="sld_Value" Grid.Column="1"
                Minimum="{Binding SliderMinVal}"
                Maximum="{Binding SliderMaxVal}"
                Value="{Binding SliderValue}"
                VerticalAlignment="Center"
                SmallChange="10" LargeChange="100"/>
        <Label x:Name="Werte" Grid.Column="2"
               Foreground="Black" FontSize="25"
               FontWeight="Bold"
               VerticalAlignment="Center"
               HorizontalAlignment="Left"
               Content="{Binding ElementName=sld_Value,Path=Value}"/>
    </Grid>
</UserControl>


Und meine schönen neuen (und endlich auch von mir verstandenen - dankeschön ABT 😘 ) DependencyProperties


using System.Windows;
using System.Windows.Controls;

namespace _090_UserControlZeuch
{
    /// <summary>
    /// Interaktionslogik für LabeledSlider.xaml
    /// </summary>
    public partial class LabeledSlider : UserControl
    {
        public static readonly DependencyProperty SliderValueProperty =
            DependencyProperty.Register("SliderValue", typeof(double),
                typeof(LabeledSlider), new FrameworkPropertyMetadata(default(double),
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public static readonly DependencyProperty SliderLabelProperty =
            DependencyProperty.Register("SliderLabel", typeof(string),
                typeof(LabeledSlider), new FrameworkPropertyMetadata(default(string)));

        public static readonly DependencyProperty SliderMinValProperty =
            DependencyProperty.Register("SliderMinVal", typeof(int),
                typeof(LabeledSlider), new FrameworkPropertyMetadata(default(int)));

        public static readonly DependencyProperty SliderMaxValProperty =
            DependencyProperty.Register("SliderMaxVal", typeof(int),
                typeof(LabeledSlider), new FrameworkPropertyMetadata(default(int)));

        public double SliderValue
        {
            get => (double)GetValue(SliderValueProperty);
            set => SetValue(SliderValueProperty, value);
        }

        public string SliderLabel
        {
            get=> (string)GetValue(SliderLabelProperty);
            set => SetValue(SliderLabelProperty, value);
        }
        
        public int SliderMinVal
        {
            get=> (int)GetValue(SliderMinValProperty);
            set=> SetValue(SliderMinValProperty, value);
        }
        public int SliderMaxVal
        {
            get=> (int)GetValue(SliderMaxValProperty);
            set=> SetValue(SliderMaxValProperty, value);
        }

        
        public LabeledSlider()
        {
            InitializeComponent();
        }
    }
}


Die Implementierung im MainWindow hat eine kleine Unwegbarkeit zutage gefördert.


    <Window.DataContext>
        <local:MainViewModel x:Name="vm"/>
    </Window.DataContext>


            <local:LabeledSlider x:Name="ucSlider" SliderMinVal="{Binding MinVal, ElementName=vm}" 
                                 SliderMaxVal="{Binding MaxVal, ElementName=vm}"
                                 SliderLabel="So heisst die Minna"
                                 SliderValue="{Binding SetVal, ElementName=vm}"/>

Die Bindingengine kam wohl bei den Bindings etwas durcheinander. Danach habe ich testweise mal dir Values mit dem Elementnamen des Viewmodels verknüft und et voilá schon lief die Minna.

Anbei ein Screenshot von meinem kleinen TestWindow.

Danke Jungs! Ihr seid die Größten. Ich wink Euch aus dem Ally Pally zu am Freitag 😉

12.12.2022 - 14:17 Uhr

Hey Abt!!

Dir ist hoffentlich schon klar, daß Du NICHT der zweitbeste bist? 😘
Wie immer superschnelle Antwort und die noch mit der Präzision eines Scharfschützen. Ganz herzlichen Dank dafür.

Der Fehler sollte sich eigentlich sehr gut googlen lassen, da er sehr häufig auftritt - und soweit ich weiß nichts mit einem User Control zutun hat, sondern mit einem PropertyBinding.

Gegooglet habe ich natürlich, wurde aber aus den Antworten nicht schlau.

Nachdem ich mich in die Thematik DependencyProperty eingelesen habe, sieht das dann so aus:


public static readonly DependencyProperty SliderValueProperty =
            DependencyProperty.Register("SliderValue", typeof(int),
                typeof(LabeldSlider), new FrameworkPropertyMetadata(default(int),
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public int SliderValue
        {
            get => (int)GetValue(SliderValueProperty);
            set => SetValue(SliderValueProperty, value);
        }

Die Fehlermeldung ist weg, die gewünschte Funktionalität aber noch nicht da. Möchte heißen, daß der Slider weder auf den gewünschten Wert springt, noch daß die Minimum und Maximum - Werte hier wirklich zum tragen kommen. Momentan rührt sich das Ding noch nichtmal 😉. Aber hier bastele ich mal weiter. Da kommt Opi schon noch dahinter.

12.12.2022 - 12:45 Uhr

Hallo liebe Forenmitglieder,

ich habe mir ein kleines UserControl gebaut, welches zwei Labels und einen Slider beinhaltet. Diesem habe ich vier Properties verpasst


    public partial class LabeldSlider : UserControl
    {
        private string textContent;
        private int minVal;
        private int maxval;
        private int setval;

        public string TextContent
        {
            get { return textContent; }
            set { textContent = value; }
        }
        public int MinVal
        {
            get { return minVal; }
            set { minVal = value; }
        }
        public int MaxVal
        {
            get { return maxval; }
            set { maxval = value; }
        }
        public int SetVal
        {
            get { return setval; }
            set { setval = value; }
        }

        public LabeldSlider()
        {
            InitializeComponent();
        }
    }

Die recht überschaubare XAML hierzu (verschönert wird das Ganze noch, wenn es läuft):


<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5*"/>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
            <Label Content="{Binding ElementName=TextContent}" Foreground="White"
                   Grid.Column="0"/>
            <Slider x:Name="Slider"  Grid.Column="1"
                    Maximum="{Binding XPath=MaxVal}"
                    Minimum="{Binding XPath=MinVal}"
                    Value="{Binding XPath=SetVal}" SmallChange="1" TickFrequency="0" 
                    LargeChange="0"/>
            <Label x:Name="Werte" Grid.Column="2" 
                   Content="{Binding ElementName=Slider, Path=Value}"
                   Foreground="White"/>
    </Grid>
</UserControl>

Jetzt wollte ich das ganze Ding in eine Page integrieren und stoße jetzt beim Binding auf einen interessanten Fehler: > Fehlermeldung:

Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.int32'

Der Fehler tritt aber nur bei der Parametrierung einer bestimmten Property auf, nämich der "SetVal"


 <theme:LabeldSlider x:Name="CricketScore" 
                TextContent="Cricket StartScore" Grid.Row="1"
                                MaxVal="1000" MinVal="0"
                                SetVal="{Binding CStartScore}">
   
            </theme:LabeldSlider>

Meine Vermutung ist, daß die von mir vergebenen Properties wohl nicht ganz den erforderlichen Vorgaben entsprechen. Könnte da mal jemand drüberschauen?

06.12.2022 - 22:12 Uhr

Ein "Leg" im Dart ist ein "Durchgang". Also ein Spiel zB 501.
Mehrere Legs ergeben ein Set.
Ein oder mehrere Sets ergeben ein Match (zB zwischen zwei Personen).){gray}

Leider gibt es auf der Profi - Tour nur zwei Turniere, die im Set - Modus gespielt werden. Den World Grand Prix und die bald anstehende Weltmeisterschaft, zu der ich am nächsten Mittwoch aufbreche. Leider nur als Zuschauer / Unterstützer meines Freundes, der bei der diesjährigen Ausgabe wieder mitspielt.

Edit: Dafür habe ich jetzt meinen 4500. Beitrag hier geschrieben, juhu!

Lass Dir dazu von mir herzlich gratulieren.

06.12.2022 - 12:52 Uhr

Anhand der Variablenbezeichnung drängt sich mir der Gedanke auf, dass wir an ähnlichen Projekten arbeiten ?!?. Ich mach grad was für Darts.

24.11.2022 - 17:55 Uhr

Vermutlich reicht es einfach Focusable auf false zu setzen, damit der Button nicht fokusiert wird.
Musst du mal prüfen.

Ja bin ich denn komplett mit Blindheit geschlagen? Diese Eigenschaft hab ich trotz stundelanger Sucherei nicht gefunden. Und genau diese hat den gewünschten Effekt erzielt.

Herzlichen Dank T-Virus und auch an alle anderen.

24.11.2022 - 03:59 Uhr

Liebe Freunde,

ich steige derzeit tiefer in WPF und MVVM ein und bin jetzt auf ein Phänomen gestoßen, zu dem mich kein Google - Treffer schlauer machen konnte:

Ich habe ein Window mit 12 Buttons, die ich aber brav per Command-Binding mit Parametern an das ViewModel gebunden habe. Habe ich einen dieser Button gedrückt (und natürlich das Command ausgeführt), wird dieser Button immer wieder ausgelöst, wenn ich die Leertaste betätige.

Eine "IsFocussed" oder ähnliche Eigenschaft habe ich nicht gefunden, die ich dann über einen Converter auf False setzen könnte.

In diesem Window fange ich auch einige Tasten ab, um Hotkeys zum Scoring zur Verfügung zu haben. Das ganze soll die Windows Umsetzung des Dart - Spieles "SplitScore§ werden.

Danke schonmal im voraus

14.09.2021 - 20:37 Uhr

Hallo Caveman

Es hat eine Weile gedauert, bis ich wieder darüber gestolpert bin. Dein Tip hat 100%ig funktioniert. Herzlichen Dank dafür.

20.08.2021 - 15:08 Uhr

Hallöle und einen schönen sonnigen Freitag liebe Gemeinde.

Ich befürchte daß mir mal wieder das Verständnis fehlt. Ich habe eine WPF - Anwendung erstellt, dort im Hauptfenster eine ListView erstellt mit einem Item - Template auf mein Haupt - ViewModel. Wenn ich das Projekt nun starte, behauptet mein VS2019:

Datenkontext: Ziel: Zieltyp Beschreibung
String "ListView.ItemSource, Name="lstNewBase" IENumerable Die Eigenschaft "Bases" wurde im Objekt vom Typ "String" nicht gefunden.

Interessanterweise zeigt das Fenster trotzdem alles an, was ich angezeigt bekommen möchte.


            <ListView x:Name="lstNewTool" ItemsSource="{Binding Tools}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionMode="Single" Margin="5" Width="400">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <views:ToolChangeView DataContext="{Binding}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>


Und hier das dazugehörige ViewModel


   public class ToolViewModel :ViewModelBase
    {
        private int _toolnumber;
        private string _toolname;
        private RobFrame _tooldata;
        private bool _isused;

        public bool IsUsed
        {
            get
            {
                return _isused;
            }
            set
            {
                _isused = value;
                RaisePropertyChanged(nameof(IsUsed));
            }
        }
        public int ToolNumber
        {
            get
            {
                return _toolnumber;
            }
            set
            {
                _toolnumber = value;
                RaisePropertyChanged(nameof(ToolNumber));
            }
        }        
        public string ToolName
        {
            get
            {
                return _toolname;
            }
            set
            {
                _toolname = value;
                RaisePropertyChanged(nameof(ToolName));
            }
        }      
        public RobFrame ToolData
        {
            get
            {
                return _tooldata;
            }
            set
            {
                _tooldata = value;
                RaisePropertyChanged(nameof(ToolData));
            }
        }
        public ToolViewModel()
        {
            ToolNumber = 0;
            IsUsed = false;
            ToolName = "";
            ToolData = new RobFrame();
        }

    }

Da es gerade in Richtung Wochenende geht, wünsche ich Euch allen ein schönes solches. Herzliche Grüße aus dem sonnigen Süden

19.07.2021 - 15:04 Uhr

Hey Abt,

das passiert ja nicht wenn ich das Fenster verschiebe, sondern genau zu dem Zeitpunkt, wenn der Programmzeiger in das Modul der Transformation heineinspringt, BEVOR irgendwelche Befehle ausgeführt werden. Das ist schon ein bisschen fremdartig.

Ich programmiere diese Transformationen jetzt "zu Fuß". Ich halte Dich auf dem Laufenden, wie sich das ganze dann verhält.

Zucker braucht's nicht, wenn man selber süß genug ist 😜

19.07.2021 - 14:32 Uhr

Hey Abt!

Da fallen mir jetzt erstmal alle meine Sünden ein. Dir schulde ich ja noch einen Kaffee (Käsekuchen wolltest Du ja nicht dazu). Erstmal herzlichen Dank für die schnelle Antwort.

Ich benutze die Presentation Core nur zur Berechnung - nie zur Darstellung. Reine Faulheit, weil ja Matrix3D dort zur Verfügung gestellt wird und diverse Berechnungsschritte. Die Darstellung sollte eigentlich nie beeinflusst werden.

Dein Einwurf, dass es an den Grafiksettings liegen könnte, ist für mich auch die plausibelste Erklärung, da das Phänomen auf einem anderen Laptop nicht auftritt.

Da mir in den Anzeigeeinstellungen eine Auflösung von 3840 x 2160 empfohlen wird, dachte ich mir eigentlich hier seien 4K verbaut. Beworben wurde er damals aber mit Full HD. Es handelt sich hier um einen Lenovo P70 - 20ER003PGE.

19.07.2021 - 09:48 Uhr

Guten Morgen liebe Freunde,

mir ist da ein recht befremdliches Verhalten untergekommen: Ich erstelle ein kleines Tool zur Transformation von kartesischen Koordinaten unter Zuhilfenahme der Presentation Core.

Sobald ich folgendes Modul anspringe:


public RobFrame Tool_Trans(RobFrame pos, RobFrame oritool, RobFrame newtool)
        // Tool_Trans transformiert eine übergebene Position pos von dem Frame
        // oritool zum Frame newtool
        {
            Matrix3D m1 = new Matrix3D();
            RobFrame tempframe = new RobFrame();

            m1 = Frame2Matrix(oritool);
            m1.Invert();

            tempframe = Matrix2Frame(m1);
            tempframe = geometrischer_Operator(pos, tempframe);
            tempframe = geometrischer_Operator(tempframe, newtool);
            return tempframe;
        }

ändert sich die Skalierung des Programmfensters. Das hat dann auf meinem 4K - Display am 17'' Laptop die Auswirkung, dass nur ein Adler noch erkennen könnte, was da steht. Das komische an der ganzen Geschichte ist die Tatsache, dass im Debugger - Modus dieses Phänomen bereits auftritt, wenn der Programmzeiger auf dem "{" steht.

Gibt's da Unverträglichkeiten zu bestimmten Grafikkarten oder ist das schön öfter aufgetreten?

Ich danke Euch schonmal im Voraus.

31.01.2021 - 23:52 Uhr

Liebe Admins,

jetzt da das Forum erfolgreich umgezogen ist, erstmal meinen herzlichen Dank. Ihr habt sicher ein paar stressige Tage gehabt.

Ich persönlich würde mich sehr freuen, wenn ich Beiträgt (und vor allem die oft sehr fruchtbaren Antworten) mit einem Daumen hoch oder gar einem "rockt" beklatschen könnte. Gibt die neue Plattform sowas her?

Aber jetzt bitte keine Hektik deswegen. Ihr habt Euch eine Pause redlich verdient.

28.01.2021 - 01:18 Uhr

Soviel vorweg: OPI HAT'S JETZT KAPIERT 😉

Code wird nachgereicht. Jetzt müssen alte Säcke in's Bett. Ich bereit das morgen auf und poste es dann.

27.01.2021 - 09:07 Uhr

Seit wir in der 13. Klasse Shakespeare im Original gelesen haben hatte ich nicht mehr so viel englischen Text vor der Nase.

Damals gab's aber noch kein Google.

Erstmal Dankeschön - ich kämpfe mich jetzt da durch. Hab bitte ein bißchen Nachsicht mit mir. Mein Hirn ist nach dem Schlaganfall noch nicht auf Prozessgeschwindigkeit und die richtigen Google-Begriffe fallen mir auch noch nicht so schnell ein.

Wir sind ja quasi Nachbarn. Wenn du auf Käsekuchen stehst - hast ihn redlich verdient 😉

26.01.2021 - 14:36 Uhr

Dankeschön für die schnelle Antwort. Hast Du mir auch einen Link dazu? Ich finde nur das mit dem Frühstück

26.01.2021 - 13:53 Uhr

Der Code sieht ziemlich abenteuerich aus.

// Methode klingt nach Array,

Ganz genau. Später soll eine große Liste von Posen umgerechnet werden. Die sind aber etwas umfangreicher als nur X,Y und Z

// Zuweisung von 0 ist unnötig, da int per Default 0 ist
public int PercentageComplete { get; set; } = 0;
T-Virus

Gewohnheit. Meine Industrieroboter mögen es gar nicht, wenn sie plötzlich auf uninitialisierte Variablen stoßen. Und dann fallen auch mal schnell einige Autos pro Schicht weniger vom Band. Frisst aber kein Brot nehme ich an.

Die Progressbar ist per se erstmal gar nicht so wichtig. Es ging mir nur darum zu visualisieren, ob diese Tasks auch brav ihre Werte rauswerfen, was sie aber nicht tun.

Die von mir erstellte Klasse basiert auf einem Beispielcode aus einem youtube-Video. Dort wird aber Webclient und client.DownloadStringTasksAsync verwendet. Ich brauche einen eigenen Task und möchte diesen eben erstellen.

26.01.2021 - 12:33 Uhr

Liebes Forum,

ich experimentiere seit einigen Stunden nun mit Asynchronen Tasks herum, aber es scheint mir nicht zu gelingen.

Aufgabe ist es, 10000 Positionen als String zu kreieren und diese auszugeben (erstmal zum Verstehen des Ganzen). Darüberhinaus habe ich noch eine ProgressBar eingebaut, um den Fortschritt erkennen zu können.

Mein Aufruf im MainWindow:


 private async void  CreatePosesAsync(object sender, RoutedEventArgs e)
        {
            TBouput.Clear(); // Eine einfache Textbox zum Anzeigen

            Progress<ProgressReportModel> progress = new Progress<ProgressReportModel>();
            progress.ProgressChanged += ReportProgress;

            var watch = System.Diagnostics.Stopwatch.StartNew();

            var results = await AsynchMethods.CreateNewPosesAsync(progress);

            watch.Stop();
            var ElapsedMs = watch.ElapsedMilliseconds;

            TBouput.Text += $"Zeit benötigt: {ElapsedMs} ms";

        }

        private void ReportProgress(object sender, ProgressReportModel e)
        {
            CreateProgress.Value = e.PercentageComplete;
            PrintResults(e.CreatedPos);
        }

        private void PrintResults(string results)
        {
            
                TBouput.Text += results;

        }

Hier rufe ich folgende Methode auf:


   public static async Task<List<string>> CreateNewPosesAsync(IProgress<ProgressReportModel> progress)
        {
  
            List<string> output = new List<string>();
            List<int> Numbers = CreateArray();

            ProgressReportModel report = new ProgressReportModel();

            await Task.Run(() =>
            {
                Parallel.ForEach<int>(Numbers, async (number) =>
               {
                   String results = await  CreatePosesAsync(number);
                   output.Add(results);

                   report.CreatedPos=results;// = output;
                   report.PercentageComplete = Numbers.IndexOf(number)*100 / Numbers.Count();
                   progress.Report(report);
               });
            });

            return output;
        }
        private static async Task<string> CreatePosesAsync(int welche)
        {
            Console.WriteLine($"{welche} {Environment.NewLine}");

            Coord retval = new Coord();
            retval.X = (float)(welche);
            retval.Y = 0;
            retval.Z = 0;

            string s = $"X {retval.X},Y {retval.Y},Z {retval.Z} {Environment.NewLine}";
            
            // Diese Zeile ist wahrscheinlich falsch
            await Task.CompletedTask;
            // aber was muss dort wirklich hin?

            return s;

        }

Für die Progressbar habe ich folgendes ReportModel erstellt:


    public class ProgressReportModel
    {
        public int PercentageComplete { get; set; } = 0;
        public string CreatedPos { get; set; }        
    }

Ich habe schon einiges durchprobiert, aber es bleibt stets asynchron (also das Windows lässt sich in der Zeit nicht verschieben). Online finden sich ja einige Beispiele, aber die machen mir nicht den Eindruck, als wenn sie in meine Aufgabe hineinpassen, da "Sleep" ja nicht unbedingt zur Geschwindigkeit beiträgt.

Mein Endziel bei der ganzen Geschichte ist, später dann kartesische Koordinaten (und zwar verdammt viele) auf geänderte Bezugsframes umzurechnen. Dieser Teil funktioniert bereits (ist ja auch relativ einfache Mathematik), aber vor dem Fliegen haben die Götter ja bekanntlich das Laufen gesetzt (Gesetz bei Natur Daniel San - nicht Miyagi machen 😉)

22.01.2021 - 10:51 Uhr


>
( etwas runterscrollen ).

Hoppala - Dankeschön für die Info

22.01.2021 - 10:31 Uhr

Und eigentlich willst du das verhalten eines Radiobuttons haben.

Völlig richtig.
Ist der gewählt Handicap - Modus auf false, soll der andere Radio - Button aktiv sein. Im weiteren Forschen habe ich herausgefunden, daß der Converter wohl den targetType anmeckert.

Den Converter habe ich mir hier abgeschaut und ihn durch einen eigenen - sehr simplen ersetzt.


using System;
using System.Globalization;
using System.Windows.Data;

namespace DartGames_WPF.Converters
{
    public class BoolInverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return !(bool)value;
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return !(bool)value;
        }
    }
}

Und siehe da es geht.

@ TH69 - Ich habe natürlich in die Doku geschaut aber ich war auf einem ganz falschen Dampfer bezüglich der Fehlerursache. Unitialisierte Variablen sind in meinem Bereich der Industrieroboter ein absolutes No-Go. Und aus diesem Grund habe ich immer eine Initialisierung dabei. Ich danke Dir herzlich für Deine Antwort - die hat mir die Initialzündung gegeben.

Wie genau markiere ich das Problem jetzt als gelöst? Irgendwie finde ich da keinen Menüpunkt für.

Habt alle einen schönen Tag.

22.01.2021 - 07:49 Uhr

Guten Morgen liebes Forum,

ich habe in meinem WPF - Fenster zwei Radio Buttons, deren Werte sich natürlich gegenseitig ausschliessen. Beim Laden des Fensters möchte ich die IsChecked - Eigenschaft natürlich von meinem Binding abhängig auf True oder False setzen.

Natürlich muss dann der andere Button dementsprechend den invertierten Wert anzeigen. Zu diesem Zweck habe ich einen Converter (geklaut):


namespace DartGames_WPF.Converters
{
    public class BoolToOppositeBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(bool))
                throw new InvalidOperationException("The target must be a boolean");

            return !(bool)value;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}

In der Definition für das Window habe ich dann folgendes eingebaut (scheint auch richtig zu sein):


<Window x:Class="DartGames_WPF.DartGamesEinstellungen"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DartGames_WPF"
        xmlns:wpfdude="clr-namespace:DartGames_WPF.Converters"
        mc:Ignorable="d"
        Title="DartGamesEinstellungen" Height="450" Width="800" Loaded="Window_Loaded">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        <wpfdude:BoolToOppositeBoolConverter x:Key="oppositeConverter" />
    </Window.Resources>

Die Tatsache daß die Code - Abarbeitung in diesen Converter auch hineinspringt legt mir die Vermutung nahe, daß die Implementierung wohl korrekt ist.

Die Zeilen für die beiden Radio - Buttons und den eigentlichen Trigger:


<RadioButton  Name="rBP1Handicapped" IsChecked="{Binding  HandiCapped}" Visibility="{Binding HandicapMode, Converter={StaticResource BooleanToVisibilityConverter}}" Content="Handicap" />

<RadioButton  Name="rBP2HandiCapped" IsChecked="{Binding  HandiCapped, Converter={StaticResource oppositeConverter}}" Visibility="{Binding HandicapMode, Converter={StaticResource BooleanToVisibilityConverter}}" Content="Handicap" />

<CheckBox Name="cbHandicapMode" Grid.Column="3" Grid.Row="3" Content="Handicap Mode" IsChecked="{Binding HandicapMode}" />

(Margins und Columngedöns habe ich zur besseren Lesbarkeit hier entfernt)

Wenn also im Match (geht um Dartspiele) der Handicap - Modus nicht aktiv ist, sind diese beiden Radiobuttons nicht zu sehen - das läuft schonmal. Möchte ich aber eine Abhängigkeit des zweiten Buttons zum inversen Wert des Bindings herstellen, spuckt mir das ganze dann folgende Fehlermeldung innerhalb dieses Converters:

Fehlermeldung:
System.InvalidOperationException
HResult=0x80131509
Nachricht = The target must be a boolean
Quelle = DartGames_WPF
Stapelüberwachung:
at DartGames_WPF.Converters.BoolToOppositeBoolConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) in C:\Users\Rolinator\Documents\Visual Studio 2019\LerneWPF\NeuesDartGames\DartGames_WPF\BoolToOppositeBoolConverter.cs:line 16
at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
at System.Windows.Data.BindingExpression.Activate(Object item)
at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance)
at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
at MS.Internal.Data.DataBindEngine.Run(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)

Das wäre sicher mit Code-Behind lösbar, aber nach allem was ich über WPF gelesen habe, wäre das wohl nicht so ganz im Sinne des Erfinders. Hat da jemand eine Idee?

Vielen Dank schonmal im voraus und einen schönen Freitag gewünscht.

22.01.2021 - 03:27 Uhr

Hallo Mr.Sparkle,

ich wollte nur mal Dankeschön sagen für diesen sehr gut geschriebenen Artikel. Daß ich ihn nicht beim ersten mal komplett verstanden habe, lag sicher nur an mir selber.

Und wie ich jetzt ein Binding invers abfragen und manche Controls nach einem Bool'schen Binding gar nicht anzeigen kann, danach mache ich mich jetzt auf die suche.

Oder ich muss den Artikel ein drittes mal lesen.

Und ich möchte anmerken, daß der Entschluß C# zu lernen die beste Entscheidung war, um nach meinem kleinen Schlaganfall mein altes Hirn wieder auf Geschwindigkeit zu trimmen. Danke für alles

22.01.2021 - 03:16 Uhr

Ich habe mich in den letzten Tagen auch intensiv mit diesem Thema befasst und bin auf die MVVM mittels Caliburn.Micro gestoßen.

Das Video dazu findest Du hier.

Seitdem ich mich mit WPF befasse (was etwa zwei Wochen ist) hab ich diese Videos von Tim Corey regelrecht verschlungen. Hab viel Freude damit.

<edit> Meine Erste Antwort hier 8). Bis jetzt kamen nur dämliche Fragen </edit>

19.01.2021 - 02:45 Uhr

Das wonach ich tagelang gesucht habe, habe ich hier im Forum gefunden. Herzlichen Dank an alle.

Und jetzt stoße ich auf dieses Video. Ein paar Tage zu spät.

Super erklärt anhand eines Beispiels.

18.01.2021 - 20:22 Uhr

Hier gibt es eine ausführliche Einführung in MVVM mit Code-Beispielen:
>

Herzlichen Dank. Diese Einführung habe ich mir im Vorfeld zu Gemüse geführt und - offensichtlich - nicht alles verstanden. Also arbeite ich das noch ein zweites mal durch.

18.01.2021 - 20:20 Uhr

Wenn trotzdem noch nichts angezeigt wird, benötigst du INotifyPropertyChanged in deinem ViewModel, wenn du Veränderungen im Code an der gebundenen Collection machen willst, sollte es eine ObservableCollection sein.

 
public class MatchHistoryViewModel : ViewModelBase
    { 
        public ObservableCollection<MatchViewModel> MatchHistory { get; }
        public MatchHistoryViewModel()
        {
            MatchHistory = new ObservableCollection<MatchViewModel>();
        }
        public void AddEntry(MatchViewModel i)
        {
     
            MatchHistory.Add(i);
        }    
    }

So hab ich es ja auch gemacht. Auch ein PropertyChangedEventhandler ist vorhanden, der im MatchviewModel auch brav gefeuert wird.

Da müsstest du das Binding für das Window auch noch anpassen.

Sehr gerne - aber wie?

<Window x:Class="ListViewBinding.MainWindow"   
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListViewBinding"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MatchHistoryViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <DataGrid x:Name="Match" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding MatchHistory}" AutoGenerateColumns="True" Margin="-23,0,22.8,0" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Width="50" Binding="{Binding ID}"/>
                <DataGridTextColumn Header="Game" Width="150" Binding="{Binding GameName}"/>
                <DataGridTextColumn Header="Sets" Width="100" Binding="{Binding Sets2Play}"/>
                <DataGridTextColumn Header="Played" Width="100" Binding="{Binding SetsPlayed}"/>
            </DataGrid.Columns>
        </DataGrid>   
    </Grid>
    
</Window>

So, und nun zeigt's was an. Ich habe in mein Modul "Test2" einfach am Ende eingefügt

Match.DataContext = MyMatchView

. Jetzt zeigt mir das DGV mit Ausnahme der ID alles an, und wenn ich Einträge editiere, werden auch brav die Ereignisse gefeuert.

Erstmal herzlichen Dank für die Antworten. Hat wer eine Idee, warum die ID nicht angezeigt wird?

Hier nochmal die MatchHistory - Klasse:


     public class MatchViewModel : ViewModelBase
    {

        private int _ID;
        private string _GameName;
        private int _Sets2Play;
        private int _SetsPlayed;
        private int _Score0;
        private int _Score1;
        private string _Player1;
        private string _Player2;

        public int ID
        {
            get { return _ID; }
            set
            {
                _ID = value;
                RaisePropertyChanged(nameof(ID));
            }
        }
        public string GameName
        {
            get { return _GameName; }
            set
            {
                _GameName = value;
                RaisePropertyChanged(nameof(GameName));
            }
        }
        public int Sets2Play
        {
            get { return _Sets2Play; }
            set
            {
                _Sets2Play = value;
                RaisePropertyChanged(nameof(_Sets2Play));
            }
        }
        public int SetsPlayed
        {
            get { return _SetsPlayed; }
            set
            {
                _SetsPlayed = value;
                RaisePropertyChanged(nameof(SetsPlayed));
            }
        }
        public int Score0
        {
            get { return _Score0; }
            set
            {
                _Score0 = value;
                RaisePropertyChanged(nameof(Score0));
            }
        }
        public int Score1
        {
            get { return _Score1; }
            set
            {
                _Score1 = value;
                RaisePropertyChanged(nameof(Score1));
            }
        }
        public string Player1
        {
            get { return _Player1; }
            set
            {
                _Player1 = value;
                RaisePropertyChanged(nameof(Player1));
            }
        }
        public string Player2
        {
            get { return _Player2; }
            set
            {
                _Player2 = value;
                RaisePropertyChanged(nameof(Player2));
            }
        }
        
    }
    public class MatchHistoryViewModel : ViewModelBase
    { 
        public ObservableCollection<MatchViewModel> MatchHistory { get; }
        public MatchHistoryViewModel()
        {
            MatchHistory = new ObservableCollection<MatchViewModel>();
        }
        public void AddEntry(MatchViewModel i)
        {
     
            MatchHistory.Add(i);
        }    
    }
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            // Führt das Event aus und gibt den Property-Namen als Argument mit, damit WPF reagieren kann.
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

[EDIT] Auch das hat sich erledigt. Es hat sich eine negative Margin eingeschlichen (-46). Das ganze auf Null und fertig war's [/EDIT]

18.01.2021 - 10:10 Uhr

Liebes Forum,

derzeit bin ich dabei, eine WinForms - Anwendung ein bißchen aufzuhübschen und auf WPF zu übertragen. Im alten Projekt habe ich mir im Hauptbildschirm Spielstände mitgeschrieben in eine dort lokale Liste die aus Einträgen meiner Klasse(das Types böse sind, habe ich hier im Forum gelernt 😄) "MatchHistory" besteht.

Dann das Ganze über die Schnittstelle in mein Ergebnisformular geladen und dort mit einer ListView angezeigt. So weit - so gut.

Der neue Plan ist das ganze mit einem DataGridView anzuzeigen, das aber eine Datenbindung zu dieser Klasse hat.

In diesem Beitrag wurde das Thema angeschnitten und ich habe nach diesem Muster eine MatchHistoryViewModel - Klasse erstellt.

Jetzt fehlt mir wohl nur noch ein kleines Stück:

Ich habe eine lokale Variable vom Typen dieser Klasse erstellt:


private MatchHistoryViewModel _myMatchView = new MatchHistoryViewModel(); 
public MatchHistoryViewModel myMatchView
{
     get { return _myMatchView; }
     set 
     {
          _myMatchView = value;
     }
}


Beim Starten meines MainWindows füttere ich das mit Daten:

 
private void Test2()
{         
    foreach (string s in Enum.GetNames(typeof(MatchNames)))
   {
         MatchViewModel mv = new MatchViewModel
         { 
                ID=0,
                GameName=s,
                Sets2Play=3,
                SetsPlayed=0,
                Score0=0,
                Score1=0,
                Player1="Vika",
                Player2="Roli"
          };
          _myMatchView.AddEntry(mv);
     }
        
}

Anhand des Beispiels in dem o.a. Artikel habe ich dann versucht, die Bindung herzustellen.

<Window x:Class="ListViewBinding.MainWindow"   
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListViewBinding"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MatchHistoryViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <DataGrid x:Name="Match" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding _myMatchview}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Width="50" Binding="{Binding ID}"/>
                <DataGridTextColumn Header="Game" Width="150" Binding="{Binding GameName}"/>
                <DataGridTextColumn Header="Sets" Width="100" Binding="{Binding Sets2Play}"/>
                <DataGridTextColumn Header="Played" Width="100" Binding="{Binding SetsPlayed}"/>
            </DataGrid.Columns>
        </DataGrid>

Aber da kommt die Fehlermeldung: > Fehlermeldung:

Schweregrad Anzahl Datenkontext Bindungspfad Ziel Zieltyp Beschreibung Datei Zeile Projekt
Fehler 1 MatchHistoryViewModel _myMatchview DataGrid.ItemsSource, Name="Match" IEnumerable Die Eigenschaft "_myMatchview" wurde im Objekt vom Typ "MatchHistoryViewModel" nicht gefunden.

Es ist ja nicht so, daß es ich das dringend brauche. Aber verstehen möchte ich das Ganze endlich. Wahrscheinlich ist der Denkfehler riesig oder winzig.

Und nach der zweiten schlaflosen Nacht deswegen gehe ich jetzt heia.

Off Topic: Für alle ein gesundes neues Jahr.

07.01.2021 - 10:25 Uhr

Hallöle.

Ich bin gerade bei der Boardsuche auf diesen Fred gestoßen. Ist das ganze noch aktuell? Ich hab das was schönes gebastelt, weil ich selbst eine Sammlung von Dartspielen gebaut habe und dort auch nach und nach einen Computergegner (Stärke 1-12) eingebaut habe.

Allerdings arbeite ich da mit "gewünschtem" Ziel und einer einstellbaren Ungenauigkeit. Das ganze aber mit Vektoren.

02.07.2020 - 15:47 Uhr

Das liest sich für mich wie Suaheli und hilft mir null.

Dennoch danke ich Dir herzlich für Deine Antwort. Was ich dadurch gelernt habe ist, daß ich das wohl besser sein lassen sollte. Bin wohl zu blöd

<edit>

Ich habe es jetzt so umgesetzt, wie der freundliche Vietnamese in diesem Video vorführt und es tut wirklich. Allerdings muss ich tatsächlich bei den Sprachdateien einmalig das Externe Tool laufen lassen.

Ich mag zwar dämlich sein, aber Youtube - Videos kucken kann ich noch.

Das Ganze sieht jetzt so aus:

   private void Beschriften(CultureInfo ci)
        {
            Assembly a = Assembly.Load("DartGames");
            ResourceManager rm = new ResourceManager("DartGames.Lang.Language",a);
            linkLabel1.Text = rm.GetString("str_Contact");
            Tauziehen.Text = rm.GetString("str_Tauziehen");
            label1.Text = rm.GetString("str_Power");
            Settings.Text = rm.GetString("str_Settings");
            Exit.Text = rm.GetString("str_Exit");
        }
02.07.2020 - 15:10 Uhr

Im Buildvorgang steht :"Eingebettete Resource" und das Tool ist der "ResXFileCodeGenerator"

Mir ist beim Nachschauen aufgefallen, dass bei einem der Namespace gefehlt hat. Aber daran lag's wohl auch nicht.

01.07.2020 - 20:21 Uhr

Liebe Freunde,

ich dachte eigentlich, mich von meinem Schlaganfall voll erholt zu haben bis zu dem Zeitpunkt, an dem ich in ein von mir geschriebenes Programm mehrsprachige Texte verwenden wollte.

Ich habe dieses Tutorial umgesetzt (Vorschlag 3) aber ich bekomme immer die Meldung:

Fehlermeldung:
System.Resources.MissingManifestResourceException: "Für die angegebene Kultur oder die neutrale Kultur konnten keine Ressourcen gefunden werden. Stellen Sie sicher, dass Application.Text.ResStrings.resources beim Kompilieren richtig in die Assembly DartGames eingebettet wurde, oder dass die erforderlichen Satellitenassemblys geladen werden können und vollständig signiert sind."

Hat der kleine Schlaganfall mein altes Hirn jetzt komplett fritiert?

Seit zwei Tagen suche ich überall und finde keine Lösung.

Ich habe zwei Resourcedateien angelegt mit den Namen: "ResStrings.resx" und "ResStrings.de-DE.resx".

Beim Aufruf von

      public static string getString(String pattern)
        {
            return resMgr.GetString(pattern);
        }

kommt dann die o.a. Fehlermeldung.

Aufgerufen wird das ganze so:

       public Haupt()
        {
            InitializeComponent();

            var Culture = CultureInfo.CurrentCulture;
            Localization.UpdateLanguage(Culture.ToString());
           
            string f = Localization.getString("POWERED_BY");
            // nur um ma zu kucken
            Beschriften();
        }
        private void Beschriften()
        {
            label1.Text = Localization.getString("POWERED_BY");
            linkLabel1.Text = Localization.getString("CONTACT");
            Tauziehen.Text = Localization.getString("TAUZIEHEN");
        }

Alles was ich möchte ist, einige Buttons und Labels mehrsprachig zu beschriften und diverse Meldungen (Game drawn by Stalemate wird zu: Patt) je nach Sprache des Systems ändern.

Ich danke schonmal im voraus für Eure Hilfe.

13.12.2019 - 12:19 Uhr

Du gibst ja auch nirgendwo einen Text an. Was sollte da auch angezeigt werden

Herzlichen Dank. Klar - das hätte ich auch selbst sehen können wenn ich weniger verzweifelt gewesen wäre. 👍

Und noch als Anmerkung: die SubItems werden nur im View-Mode View.Details (Spaltenansicht) angezeigt (so wie man die Ansichten auch vom Windows Explorer kennt)...

Ja und wenn man das zur Laufzeit mit "List" überschreibt, dann arbeitet man auch schön im Kreis. 😄. Vielen herzlichen Dank für diesen Hinweis.

Das Problem ist hiermit gelöst und ich bedanke mich herzlich bei allen für die fruchtbaren Kommentare.

12.12.2019 - 16:44 Uhr

Hey Khalid,

erstmal vielen Dank für Deine schnelle Antwort.

Diese Version ist ein weiterer Versuch, daß die dämlichen SubItems überhaupt einmal angezeigt werden. Ich habe schon etliche Beispiele versucht umzusetzen, aber es zeigt sich NIX.

Auch durch Deine (herzlichen Dank nochmal) Korrektur der Syntax zeigen sich nur leere Items mit den Checkboxen vorne dran.

12.12.2019 - 16:18 Uhr

Liebes Forum,

bevor ich meine Frage stelle möchte ich einmal anmerken, daß ich bis jetzt jedes Problem durch die Boardsuche hier lösen konnte. Auch gefällt mir der Umgangston sehr gut.

Antworten wie: "Google" oder "such doch mal richtig" sind hier spärlich bis gar nicht zu finden.

Bei meinem aktuellen Problem habe ich nirgendwo eine Lösung gefunden. Könnte auch daran liegen, daß ich eventuell die falschen Suchbegriffe verwende.

Nun zum eigentlichen Problem:

Ich habe eine ListView (zum Abkürzen der Tippselei habe ich ihr den Namen "lv" gegeben) und möchte diese füllen. Das ist mir bis jetzt mit SubItems usw noch nie gelungen. Jetzt bin ich auf die AddRange - Methode gestoßen und daß man dort wohl eine Auflistung von Items mit einem Schlag einfügen kann. Dafür fehlt mir aber die Syntax (und ich habe schon sehr viele Versuche hinter mir).

public partial class Testform : Form
    {
        public Testform()
        {
            InitializeComponent();
        }

        private void Testform_Load(object sender, EventArgs e)
        {
            lv.View = View.List;
            lv.LabelEdit = true;
            lv.AllowColumnReorder = false;
            lv.CheckBoxes = true;
            lv.GridLines = true;

            List<ListViewItem> arrayItems = new List<ListViewItem>();

            for (int i = 0; i < 4; i++)
            {
                ListViewItem neu = new ListViewItem();
                neu.SubItems.Add((i * 10).ToString());
                neu.SubItems.Add((i * 100).ToString());

                arrayItems.Add(neu);

                


            }
           // Genau HIER finde ich nicht die richtige Syntax

??????????            lv.Items.AddRange(new ListViewItem[arrayItems]);

           // Ende von nicht gefunden.
        }
    }

Wer hilft einem dämlichen alten Sack? Für Eure Hilfe schonmal herzlichen Dank im voraus.