Laden...

Forenbeiträge von BlonderHans Ingesamt 77 Beiträge

01.12.2023 - 08:24 Uhr

Wo ist denn das Problem bzw. wo ist das von dir erwartete Verhalten dokumentiert.

Wenn die Validierung fehl schlägt, dann bleibt bei entsprechender Einstellung der Focus auf der TextBox. Somit können andere Elemente, die den Focus benötigen nicht mehr erreicht werden. EinLabelgehört aber nicht zu diesen "Ich brauche den Focus" Elementen.

22.11.2023 - 14:23 Uhr

Such mal mit dem Stichwort TreeMap in der Suchmaschine deiner Wahl, da finden sich diverse Anbieter mit so einem Control

22.11.2023 - 08:28 Uhr

Für das reine Anzeigen kannst du PreviewHandler verwenden.

Das Einbetten so eines PreviewHandlers in WPF siehst du in PreviewHost (GeeLaw)

19.11.2023 - 19:21 Uhr

Zitat von Th69

BlonderHans, du hast noch einen kleinen C&P Fehler in

Jo, das kommt davon, wenn man keine Unit-Tests schreibt.

19.11.2023 - 13:44 Uhr

Im Anhang habe ich dir mal ein Beispiel-Projekt gepackt, was deinem recht nahe kommt.

Inklusive Dependency-Injection (Registrierung erfolgt in der Program.cs) und einen Framework für MVVM (reactiveUI) was das Handling erheblich vereinfacht.

So sehen z.B. die ViewModels aus:

public class MainWindowViewModel : ViewModelBase
{
    private readonly Page1ViewModel _page1;
    private readonly Page2ViewModel _page2;

    public ReactiveCommand<Unit, Unit> Page1Command { get; }
    public ReactiveCommand<Unit, Unit> Page2Command { get; }
    [Reactive] public PageViewModelBase CurrentPage { get; private set; }

    public MainWindowViewModel( Page1ViewModel page1, Page2ViewModel page2 )
    {
        _page1 = page1;
        _page2 = page2;

        Page1Command = ReactiveCommand.CreateFromTask( OnPage1 );
        Page2Command = ReactiveCommand.CreateFromTask( OnPage2 );
    }

    private async Task OnPage1()
    {
        CurrentPage = _page1;
        await _page1.InitializeAsync();
    }
    
    private async Task OnPage2()
    {
        CurrentPage = _page2;
        await _page1.InitializeAsync();
    }
}

sowie

public class Page1ViewModel : PageViewModelBase
{
    [Reactive] public string Id { get; set; }
    [Reactive] public string Firstname { get; set; }
    [Reactive] public string Lastname { get; set; }
}

und die View

<Window x:Class="WpfApp.Views.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:local="clr-namespace:WpfApp.Views"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:viewmodels="clr-namespace:WpfApp.ViewModels"
        Title="MainWindow"
        Width="800"
        Height="450"
        d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False,
                                   Type={x:Type viewmodels:MainWindowViewModel}}"
        mc:Ignorable="d">
    <DockPanel>
        <StackPanel DockPanel.Dock="Left">
            <Button Command="{Binding Page1Command}"
                    Content="Page1" />
            <Button Command="{Binding Page2Command}"
                    Content="Page2" />
        </StackPanel>
        <ContentControl Content="{Binding CurrentPage}">
            <ContentControl.Resources>
                <DataTemplate DataType="{x:Type viewmodels:Page1ViewModel}">
                    <GroupBox Background="LightCoral"
                              Header="Page 1">
                        <StackPanel>
                            <DockPanel>
                                <Label Content="Id:" />
                                <TextBox Text="{Binding Id, UpdateSourceTrigger=PropertyChanged}" />
                            </DockPanel>
                            <DockPanel>
                                <Label Content="Firstname:" />
                                <TextBox Text="{Binding Firstname, UpdateSourceTrigger=PropertyChanged}" />
                            </DockPanel>
                            <DockPanel>
                                <Label Content="Lastname:" />
                                <TextBox Text="{Binding Lastname, UpdateSourceTrigger=PropertyChanged}" />
                            </DockPanel>
                        </StackPanel>
                    </GroupBox>
                </DataTemplate>
                <DataTemplate DataType="{x:Type viewmodels:Page2ViewModel}">
                    <local:Page2Control />
                </DataTemplate>
            </ContentControl.Resources>
        </ContentControl>
    </DockPanel>
</Window>

Das kannst da als Basis für weitere Experimente verwenden.

18.11.2023 - 09:30 Uhr

Da ist doch mal wesentlich mehr Fleisch dran.

Wenn du jetzt noch verraten könntest WO der ominöse Button sein soll (im MainWindow, Page1 oder Page2) und welche Eigenschaft (also von welcher Klasse und Instanz) damit geändert werden soll, dann wäre das Bild komplett.

Zitat von CSharpNewbie2022

Ich habe [...] und auch die Dependency Injektion und wollte mein Projekt verbessern.

Davon sehe ich hier aber nichts.

17.11.2023 - 09:30 Uhr

Ich versuche mal zu ergründen was du so willst.

Button auf dem Window drücken [...] soll etwas in der page passieren

Eine Möglichkeit ist beschrieben in Befehlsübersicht

11.11.2023 - 13:02 Uhr

Dann hast du es ja jetzt verstanden

10.11.2023 - 17:50 Uhr

Ich habe deinen Code mal nur so überflogen allerdings sehe ich ich fast überall wo ich hinschaue Fehler, das es mir zu viele sind als jetzt auf jeden einzugehen.

Schau dir doch einfach mal in Ruhe die Beispiele an die du genannt bekommen hast und versuche mit denen zu arbeiten und vor allem das Konzept MVVM zu verstehen.

10.11.2023 - 13:19 Uhr

Zitat von tomschrot

  • void Reset(): setzt den Index aufs 1. Element

In der Original Beschreibung steht

Sets the enumerator to its initial position, which is before the first element in the collection.

Der Index steht also nach Reset() vor dem ersten Element und nicht darauf.

08.11.2023 - 07:51 Uhr

Wenn du dein Problem etwas eleganter beschreiben könntest, könnte man dir bestimmt helfen.

z.B. Ein Window (auf deutsch Fenster) besteht aus 4 Fenstern … ah, ja

Ich kann mir nicht vorstellen, was du wirklich haben möchtest.

22.10.2023 - 17:51 Uhr

Wenn du weiter Kopfschmerzen haben möchtest, dann mach mit diesem IndexOf weiter.

Wenn du es einfach lösen möchtest, dann verwendest du z.B. folgendes

var doc = new XmlDocument();
doc.Load( "WieAuchImmerDieHeisst.emp" );

var elements = doc.GetElementsByTagName( "S114x1894" )
    .OfType<XmlElement>()
    .Where( e => e.Attributes is not null && e.Attributes.OfType<XmlAttribute>().Any( a => a.Name == "A2011" && a.Value == "XXXValueSet1YYY" ) )
    .ToList();

In elementsfindest du jetzt alle betroffenen Elemente und kannst diese jetzt ganz gemütlich ändern.

Am Ende speicherst du den ganzen Kladderadatsch wieder ab mit doc.Save( "WieAuchImmerDieHeisstBearbeitet.emp" );

Du kannst dir auch XPath anschauen

21.10.2023 - 10:07 Uhr
  • Wenn du Probleme mit einer Textdatei hast, dann brauchen wir zum Ausprobieren diese Textdatei und nicht den schon interpretierten Inhalt derselbigen.
  • Wenn du XML zeigen möchtest, dann verwende doch bitte die XML-Code-Tags dafür, dann fällt allen das Lesen leichter
<root>
  <S114x1894 A2011="SMT-10M-PS-24V-E-0,3-L-M8D / 551375 / C-Nut" A2012="FES.551375;IEC_symbol\;1\;146\;6;;FES.551375;IEC_symbol\;1\;146\;6;MURR.7000-41211-0000000;MURR.7000-12221-6341000;Artikelnummer;;1;1"/>
  <S114x1894 A2011="SMT-8M-A-PS-24V-E-0,3-M8D / 574334 / T-Nut" A2012="FES.574334;IEC_symbol\;1\;146\;6;;FES.574334;IEC_symbol\;1\;146\;6;MURR.7000-41211-0000000;MURR.7000-12221-6341000;Artikelnummer;;1;1"/>
</root>
  • Bei XML sollte man niemals mit dem ungeparsten rohen Text arbeiten (also kein RegEx oder IndexOf etc.). Dafür gibt es Parser und mit dem was die rauswerfen kannst du dann deine Suche starten.
    Ausnahme: Du willst einen eigenen Parser schreiben
12.10.2023 - 17:51 Uhr

Nun du willst Daten von einem SQL-Server haben. Dann würde ich zunächst einmal danach suchen, wie man das mit dem SQL-Server macht.

Wenn du das herausgefunden hast, dann schaust du, wie man das in C# schreibt.

BTW Stake Overflow Die Seite heißt StackOverflow und das ist ein bekannter Fehler beim rekursiven Programmieren (wenn man die Abbruchbedingung vergessen hat oder es wirklich tief in den Kaninchenbau geht)

30.09.2023 - 13:41 Uhr

Halten wir fest, bei mir fliegt so etwas im Review heraus. Sollte die Implementierung nach Lehrbuch Schwierigkeiten machen (zu aufwendig, zu langsam, ...) dann würde ich auch einen pragmatischen Ansatz verfolgen. Aber erst dann.

29.09.2023 - 20:53 Uhr

Zitat von Th69

Technisch kann man zwar MVVM auch für WinForms benutzen, jedoch sind View und ViewModel meistens doch logisch voneinander abhängig, so daß man für eine neue UI-Technologie auch häufig die VMs anpassen muß (wenn es um mehr geht als das Binden von Strings und Zahlenwerten, z.B. UI-technologische Datentypen).

Edit:

Als Beispiel für einen UI-technologischen Datentyp die Anzeige eines Bildes:

  • für WinForms: System.Drawing.Image/Bitmap
  • für WPF: System.Windows.Media.ImageSource

Wenn man im ViewModel Datentypen aus dem UI-Framework verwendet, dann hat man schon im Ansatz etwas falsch gemacht. So etwas sollte bei jedem Review sofort gerügt werden.

Nehmen wir mal das Beispiel mit dem Bild und wie man das bei WPF/MAUI macht:

Im ViewModel eine Eigenschaft vom Typ byte[] (Bild-Rohdaten) oder string (Verweis auf Bild per Dateiname oder URL) erstellen und diese Eigenschaft in der View an die Source Eigenschaft des ImageControls binden.

qed

28.09.2023 - 11:57 Uhr

Ich hätte hier mit await Task.Yield() gearbeitet, das funktioniert bei mir mit den Dialogen immer sehr gut.

21.09.2023 - 13:56 Uhr

Versuch doch mal die App.xaml exakt genau so wie ich die gepostet habe.

Genau aus diesem Grund habe ich die auch komplett gepostet

21.09.2023 - 13:26 Uhr

Weil du irgendwo auch sagen musst, was er wie wo laden soll. Z.B. in der App.xamlweil das für die gesamte Anwendung gilt:

<Application x:Class="WpfAppToolBar.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfAppToolBar"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Themes/Generic.xaml" />
                <ResourceDictionary Source="Themes/GenericSeite2.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
        
    </Application.Resources>
</Application>
21.09.2023 - 10:55 Uhr

Weil dir zu deinem Control noch ein Style fehlt. Ohne Style weiß WPF doch nicht wie es das darstellen soll. Ich habe es dir mal in die App.xaml eingebaut:

<Application x:Class="WpfAppToolBar.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfAppToolBar"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
     
        <Style TargetType="{x:Type local:NavigationSeite2}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:NavigationSeite2}">
                        <ContentPresenter ContentSource="Text"
                                          TextElement.Foreground="{TemplateBinding Foreground}" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        
    </Application.Resources>
</Application>
07.09.2023 - 09:39 Uhr

So, mit der OneDrive Version 23.169.0813.0001 ist das behoben worden.

06.08.2023 - 23:02 Uhr

Wenn ich so deine Beschreibung lese und die (erste) Frage dazu, dann frage ich mich ob du das wirklich ernst meinst.

Ich füge der Liste immer wieder etwas an. Wird das jetzt immer länger, wenn ich die nicht leere?

Und wo und wann ein Clear erforderlich ist ... äh, ja dann, wenn es die Situation - die bislang nur du kennst - erfordert.

27.07.2023 - 14:19 Uhr

Das Laden der Daten sollte nicht durch den Konstruktor angestossen werden. Es ist wesentlich geschickter dieses erst dann zu erledigen, wenn dieses erforderlich ist (z.B. wenn die View wirklich angezeigt wird).

Meine ViewModels basieren alle auf:

public abstract class ViewModelBase : ReactiveObject
{
    [Reactive] public bool IsInitialized { get; private set; }
    public async Task InitializeAsync( CancellationToken cancellationToken = default )
    {
        IsInitialized = false;
        await OnInitializeAsync( cancellationToken );
        IsInitialized = true;
    }
    
    protected virtual Task OnInitializeAsync( CancellationToken cancellationToken ) => Task.CompletedTask;
}

Die konkreten ViewModels überschreiben die OnInitializeAsync-Methode wenn es irgendwelche Daten zu laden gibt.

Per DependencyInjection bekommt jede View (Window, Page) das ViewModel im Konstruktor übergeben und beim Erscheinen der View wird die Initialisierung des ViewModels angestossen.

public class MainWindow : Window
{
    public MainWindow( MainWindowViewModel viewModel )
    {
        InitializeComponent();
        DataContext = viewModel;
        Appearing += async ( s, e ) => await viewModel.InitializeAsync();
    }
}

Das funktioniert wie gesagt bei einem Window als auch bei einer Pageganz wunderbar.

10.07.2023 - 13:16 Uhr

So am Rande bemerkt:

Bei der aktuellen Definition wird es im Übrigen schwierig werden zwischen nichts gewählt (also alle Bits auf 0) und StdVerzListenFlag.DESKTOPzu unterscheiden, denn beide Zustände haben den Wert 0.

07.07.2023 - 15:34 Uhr

Wie löst man das, wenn man dem Peter erzählt er soll doch bitte das Geld einstecken und dann mit dem Herbert zum Essen fährt und nicht bezahlen kann?

Nimm den zum Essen mit, der das Geld eingesteckt hat, wenn du ernsthaft bezahlen möchtest.

Mit den Objekten und Instanzen verhält es sich genauso. Obwohl Peter und Herbert beide vom Typ Mensch sind unterscheiden sich die Instanzen eben dadurch das die Instanz Peter das Geld hat und die Instanz Herbert eben nicht.

public class Mensch
{
    public decimal Geld { get; set; }
}

var peter = new Mensch();
peter.Geld += 100;
var herbert = new Mensch();
05.07.2023 - 23:19 Uhr

Du arbeitest mit DREI Instanzen vom LoginVM.

Die erste Instanz erzeugst du im BasicWindowVM

namespace WpfVisible.ViewModel
{
    public class BasicWindowVM : BaseViewModel
    {
        public BaseViewModel ViewModel { get; set; }

        public BasicWindowVM()
        {
            ViewModel = new LoginVM(); // <<== ERSTE Instanz
        }
    }
}

und die zweite Instanz in der BasicWindowView

<Window x:Class="WpfVisible.View.BasicWindowView"
        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:WpfVisible.View"
        xmlns:vm="clr-namespace:WpfVisible.ViewModel"
        xmlns:converter="clr-namespace:WpfVisible.ViewModel.Converters"
        mc:Ignorable="d"
        Title="BasicWindowView"
        Height="450"
        Width="800">
    <Window.DataContext>
        <vm:BasicWindowVM />
    </Window.DataContext>
    <Window.Resources>
        <!-- ZWEITE Instanz -->
        <vm:LoginVM x:Key="LoginVM" />
        <converter:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    </Window.Resources>
    <Grid>
        <DockPanel>
            <ToggleButton DockPanel.Dock="Top"
                          Content="Toggle"
                          Visibility="{Binding Source={StaticResource LoginVM}, Path=IsAuthenticated, Mode=OneWayToSource, Converter={StaticResource BooleanToVisibilityConverter}}" />
            <!--Visibility="{Binding Source={StaticResource LoginVM}, Path=IsAuthenticated, Converter={StaticResource BooleanToVisibilityConverter}}"-->
            <ContentControl Content="{Binding ViewModel}" />
        </DockPanel>
    </Grid>
</Window>

und die dritte im LoginView

<UserControl x:Class="WpfVisible.View.LoginView"
             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:WpfVisible.View" 
             xmlns:vm="clr-namespace:WpfVisible.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.DataContext>
        <!-- DRITTE Instanz -->
        <vm:LoginVM/>
    </UserControl.DataContext>
    <Grid>
        <Button Content="Login" VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" Command="{Binding LoginCommand}"/>
    </Grid>
</UserControl>

Der Login-Button ist mit der dritten Instanz verknüpft und der ToggleButton mit der zweiten Instanz. Da ist es auch kein Wunder, dass dann nichts passiert.

Das Positive: Mehr falsch machen kann man fast nicht mehr.

Hier nun die Änderungen, die notwendig sind:

BasicWindowView.xaml

<Window x:Class="WpfVisible.View.BasicWindowView"
        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:WpfVisible.View"
        xmlns:vm="clr-namespace:WpfVisible.ViewModel"
        xmlns:converter="clr-namespace:WpfVisible.ViewModel.Converters"
        mc:Ignorable="d"
        Title="BasicWindowView"
        Height="450"
        Width="800">
    <Window.Resources>
        <converter:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    </Window.Resources>
    <Window.DataContext>
        <vm:BasicWindowVM />
    </Window.DataContext>
    <Grid>
        <DockPanel>
            <ToggleButton DockPanel.Dock="Top"
                          Content="Toggle"
                          Visibility="{Binding ViewModel.IsAuthenticated, Converter={StaticResource BooleanToVisibilityConverter}}" />
            <ContentControl Content="{Binding ViewModel}" />
        </DockPanel>
    </Grid>
</Window>

LoginView.xaml

<UserControl x:Class="WpfVisible.View.LoginView"
             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:WpfVisible.View"
             xmlns:vm="clr-namespace:WpfVisible.ViewModel"
             mc:Ignorable="d"
             d:DesignHeight="450"
             d:DesignWidth="800">
    <Grid>
        <Button Content="Login"
                VerticalAlignment="Center"
                HorizontalAlignment="Center"
                Width="200"
                Command="{Binding LoginCommand}" />
    </Grid>
</UserControl>

BaseViewModel.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfVisible.ViewModel
{
    public abstract class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null )
        {
            PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
        }

        private bool isAuthenticated;

        public bool IsAuthenticated
        {
            get { return isAuthenticated; }
            set { isAuthenticated = value; OnPropertyChanged(); }
        }

    }
}
05.07.2023 - 21:10 Uhr

Das ist der Logik hinter dem ToggleButton völlig egal, von wem und woher er die Information bekommt, er muss sie nur bekommen und die Benachrichtigung muss funktionieren, dann arbeitet der wie zu erwarten und genau das sollte das Beispielprojekt zeigen (nicht mehr).

05.07.2023 - 20:37 Uhr

Also an dem ToggleButton liegt es definitiv nicht. Siehe Projekt im Anhang.

05.07.2023 - 12:07 Uhr

Dein Hauptproblem ist der Binding-Mode OneWayToSource

Siehe dazu Übersicht über Datenbindung - Richtung des Datenflusses

So sollte das funktionieren

<ToggleButton 
  HorizontalAlignment="Left" 
  Width="50" 
  Visibility="{Binding Source={StaticResource LoginVM}, Path=MenuVisibility, Mode=OneWay}" 
  Command="{Binding OpenMainMenuCommand}">

Das Setzen von UpdateSourceTrigger ist überflüssig, denn eine Änderung der Eigenschaft erfolgt doch gar nicht über die View.

Das Setzen von Mode ist auch überflüssig, da es sich bei OneWay um den Default-Wert handelt.

Darüber hinaus sollte man im ViewModel keine Typen vom UI-Layer/-Framework verwenden (wie z.B. hier Visibility). Hier macht es wesentlich mehr Sinn im ViewModel eine Eigenschaft vom Typbool zu haben (denkbarer Name wäre IsAuthenticated) und der Bindung dann einen Converter an die Hand zu geben, der diesen bool Wert in den passenden Visibility Wert konvertiert. Damit lässt man dem UI-Designer alle Freiheiten zur Darstellung.

04.07.2023 - 08:57 Uhr

Kann mir jemand erklären, warum der Einstellungsdialog von identischen OneDrive-Versionen auf zwei nahezu identischen Systemen (VMware) so unterschiedlich aussieht?

Den moderneren Dialog bekomme ich auf dem System wo auch Visual Studio 2022 installiert ist, falls es da einen Zusammenhang gibt.

03.07.2023 - 17:21 Uhr

Was sagt denn der Stacktrace wenn du einen Breakpoint auf die Zeile _candleKeyLevel = fixedProfileOriginScale; setzt?

Das sollte deine Frage eigentlich hinreichend beantworten.

02.07.2023 - 12:54 Uhr

Hast du dabei bedacht, dass ein fehlgeschlagener INSERT trotzdem den Auto-Inkrement Wert erhöht?

Wenn du damit leben kannst ist alles ok. Ich sah allerdings schon so einige in einer ähnlichen Situation aus allen Wolken fallen.

14.06.2023 - 10:30 Uhr

Also ich kann keinen Unterschied feststellen.

  • MAUI
<Grid BackgroundColor="#c0e1e1" />
  • WPF
<Grid Background="#c0e1e1" />
  • WinForms
BackColor = Color.FromArgb(   192  ,   225  ,   225   );

Und was dabei rauskommt (MAUI, WPF, WinForms) sieht man im Screenshot

13.06.2023 - 10:35 Uhr

Den Weg der doppelten Konvertierung musst du nicht gehen, es reicht ein simpler Cast IDNrHaupt = (int)DR["IDNrHaupt"]

EDIT: Oh, zwei Stühle eine Meinung ...

11.06.2023 - 00:42 Uhr

Stell dir einmal vor so ein Control wie die TextBox wäre so konzipiert wie dein UserControl - dann könntest du dieses Binding

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

nicht einfach so machen, sondern du müsstest im CodeBehind auf den DataContext dieser TextBox zugreifen und dort der Eigenschaft Text den entsprechenden Wert zuweisen. Sehr gruselig.

Gottlob wurde das nicht so gemcht und es gibt eben diese DependencyProperty.

05.06.2023 - 06:55 Uhr

Eine win32.dll kenne ich von Windows nicht. Meinst du eventuell die Windows-API (formerly known as Win32-API)?

Dann sollte das eigentlich deine Frage beantworten:

Mithilfe der Windows-API können Sie Anwendungen entwickeln, die auf allen Windows-Versionen erfolgreich ausgeführt werden, und gleichzeitig die für jede Version einzigartigen Features und Funktionen nutzen. (Beachten Sie, dass dies früher als Win32-API bezeichnet wurde. Der Name Windows-API spiegelt seine Wurzeln in 16-Bit-Windows und seine Unterstützung unter 64-Bit-Windows genauer wider.)

Quelle: Windows-API-Index

Generell ist es eine gute Idee, sich beim Hersteller zu erkundigen.

02.06.2023 - 10:24 Uhr

Zitat von Kriz

-> Würde das hier gern schöner formatieren, aber es wird leider nicht richtig übernommen...

Du hast für deinen Code(-Block) die Code Formatierung verwendet und nicht den direkt daneben liegenden Button für Code-Block einfügen.

Mit Code-Block einfügen sieht das dann so aus:

switch (overlay.Type)
{
    case OverlayType.Ellipse:
        ShowEllipse = true;
        ShowRectangle = false;
        ShowPath = false;
        break;
    case OverlayType.Rectangle:
        ShowEllipse = false;
        ShowRectangle = true;
        ShowPath = false;
        break;
    case OverlayType.Path:
        ShowEllipse = false;
        ShowRectangle = false;
        ShowPath = true;
        break;
    default:
        break;
}

Die Code Formatierung verwendest du, wenn du im Text etwas als Code formatieren möchtest, wie z.B. den Typen string oder deinen overlay.Type.

02.06.2023 - 10:09 Uhr

WÄre es nicht einfacher so?

public bool ShowEllipse => overlay.Type == OverlayType.Ellipse;
public bool ShowRectangle => overlay.Type == OverlayType.Rectangle;
public bool ShowPath => overlay.Type == OverlayType.Path;

und immer wenn sich in overlay die Eigensschaft Type ändert, dann folgenden Code noch ausführen

OnPropertyChanged(nameof(ShowEllipse));
OnPropertyChanged(nameof(ShowERectangle));
OnPropertyChanged(nameof(ShowPath));

Alternativ gäbe es auch noch diesen EnumToBoolConverter aus dem CommunityToolkit

29.05.2023 - 19:58 Uhr

Zitat von RobertStahl

Perfekt, danke, aber das @GWu1 wird anscheinend benötigt für die Zuweisung im Update-Befehl

Ja, ähm ... genau ... ich habe doch auch nicht gesagt "entferne das @ Zeichen" sondern du musst bei Parameters.Add den Parameter-Namen so verwenden wie du ihn im Statement geschrieben hast. Und zwar genau so.

Denn

Parameters can be prefixed with either :, @, or $.

aber für einen Präfix musst du dich zwingend entscheiden und der Parameter-Name ist immer mit Präfix anzugeben.

29.05.2023 - 10:05 Uhr

Wenn du es allerdings ganz bequem haben möchtest, dann kannst du auch Dapper verwenden. Dann würde das so aussehen:

class GrenzwerteDto
{
    public int ProductReference { get; set; }
    public decimal GWu1 { get; set; }
}

connection.Open();
var data = new GrenzwerteDto { ProductReference = 42, GWu1 = 12.45, };
connection.Execute( "UPDATE Grenzwerte SET GWu1 = @GWu1 WHERE REF_Produkt = @ProductReference", data );

oder mit noch weniger Boilerplate

connection.Open();
connection.Execute( "UPDATE Grenzwerte SET GWu1 = @GWu1 WHERE REF_Produkt = @ProductReference", 
    new { ProductReference = 42, GWu1 = 12.45, } );

Kann man sich überlegen

29.05.2023 - 09:45 Uhr

Da sind drei Dinge falsch.

1. Anführungszeichen

command.CommandText = $"UPDATE Grenzwerte SET GWu1 = '@GWu1'  WHERE REF_Produkt = 'Int aus einer Textbox'

Die Parameter kümmrn sich von ganz alleine darum, dass die Werte korrekt übergeben werden. Jede weitere Bevormundung durch Anführungszeichen o.ä. empfinden diese als übergriffig.

So ist es korrekt

command.CommandText = $"UPDATE Grenzwerte SET GWu1 = @GWu1  WHERE REF_Produkt = 'Int aus einer Textbox'

2. Parameters.Add verwenden

Statt

command.Parameters.AddWithValue("GWu1", DbType.Decimal).Value =  NudGw_Gwu1.Value;

so

command.Parameters.Add("GWu1", DbType.Decimal).Value =  NudGw_Gwu1.Value;

3. Parameter-Name

Der Name des Parameters lautet exakt so wie er in dem Command-Text angegeben wurde - wirklich exakt und kein "so irgendwie in der Art evetuell"

Wenn dort der Parameter also als @GWu1 angegeben wurde, dann ist genau das auch der Name.

Also statt

command.Parameters.Add("GWu1", DbType.Decimal).Value =  NudGw_Gwu1.Value;

so

command.Parameters.Add("@GWu1", DbType.Decimal).Value =  NudGw_Gwu1.Value;
28.05.2023 - 18:44 Uhr

Es ist etwas konfus was du da schreibst ... du könntest ruhig etwas konkreter werden, dann könnte man auch konkreter Hilfestellung geben.

Worauf du dich mit getters/setters beziehst erschließt sich mir nicht (im Code von Palladin sehe ich nur Getter).

Hast du dir das Spezification Pattern mal angesehen? Das ist eigentlich für so etwas der richtige Ansatz.

27.05.2023 - 03:09 Uhr

Hallo, du hast den klassischen Anfängerfehler (nicht falsch verstehen, den macht gefühlt jeder Programmierer auf seiner Reise - ich auf jeden Fall auch) gemacht.

Wenn du ein SQL-Statement per string zusammenbaust, dann ist das ein grober Fehler - Grüße von Little Bobby Tables.

Sicherer und einfacher funktioniert das mit Parametern denn die Parameter sorgen dafür, dass die Werte beim SQL-Server auch korrekt ankommen.

24.05.2023 - 17:22 Uhr

Ich sprach eigentlich von diesem VERSIONINFO und nicht von System.Version, denn dort passt es problemlos, weil dort für Build (und auch die anderen Teile) ein Int32 verwendet wird.

24.05.2023 - 09:02 Uhr

Wenn der Build bei 100.000 anfangen soll wird dann auch die Struktur in VERSIONINFO geändert?

Dort wird die Version ja als 64bit Wert angelegt (4x 16bit = 0..65535).

Meine Glaskugel ist in dem Bereich aber ganz wolkig, somit lassen wir uns überraschen.

22.05.2023 - 20:06 Uhr

Da wir nicht wissen, wie die Versionsnummern in der Zukunft weitergezählt werden, sollte man aber auch zwingend Major und Minor daraufhin prüfen, ob diese auch wirklich 10 bzw. 0 sind. Sonst ist die Verwirrung groß wenn (warum auch immer) Windows 12 die Version 10.1.12345.0 hat.

21.05.2023 - 11:21 Uhr

Kannst du mal mit DISKPART die Attribute des Laufwerks prüfen?

DISKPART
SELCT DISK 6
ATTRIBUTES DISK

Dann sollte er so etwas anzeigen

Aktueller schreibgeschützter Zustand: Nein
Schreibgeschützt  : Nein
Startdatenträger  : Nein
Auslagerungsdatei-Datenträger  : Nein
Ruhezustandsdatei-Datenträger  : Nein
Absturzabbild-Datenträger  : Nein
Clusterdatenträger : Nein

Eventuell ist bei Windows 10 dort der Schreibschutz drin.

18.05.2023 - 10:32 Uhr

Probier mal diese kleine Änderung am Code:

public void AppendText(string text)
{
    _text += text;
    this.StateHasChanged();
}
14.05.2023 - 13:14 Uhr

Das riecht ein wenig nach Specification Pattern