Laden...
M
Michael Hößel
myCSharp.de - Member
15
Themen
46
Beiträge
So langsam wirds!
Letzte Aktivität
vor 9 Monaten
Dabei seit
21.07.2006
Alter
64
Beruf
Dipl.-Ing. IT
Herkunft
Deutschland
Interessen
Flugmodellbau, Mountainbiken
Website
Erstellt vor 10 Monaten

Ergänzung: Wenn ich alle Spalteneiner Row ändere, funktioniert es. Angemeckert werden die nicht editierten Spalten.

Erstellt vor 10 Monaten

Für den dynamischen Inhalt eines Datagrid habe ich eine ValidationRule geschrieben:

        public override ValidationResult Validate(object value,
            System.Globalization.CultureInfo cultureInfo)
        {
            var bg = (BindingGroup)value;
            DataRowView rView = bg.Items[0] as DataRowView;

            if (Columns != null)
            {
                bool result = true;
                foreach (string name in Columns.Keys)
                {
                    object iValue = DBNull.Value;
                    if (result)
                    {
                        bool isDirty = bg.IsDirty;
                        bool isSealed = bg.IsSealed;
                        result = bg.TryGetValue(rView, name, out iValue);
                    }
                    if (!result)
                        return new ValidationResult(false, $"Propertie \"{Columns[name].ColumnHeader}\" not found!");
                    else if (iValue == DBNull.Value)
                        return new ValidationResult(false, $"\"{Columns[name].ColumnHeader}\" is necessary!");
                    else
                    {
                        switch (Columns[name].DataType)
                        {
                            case ApClasses.EnumDataType.NVarChar100:
                            case ApClasses.EnumDataType.Bit:
                                if (iValue.ToString().Trim().Length == 0)
                                    return new ValidationResult(false, $"\"{Columns[name].ColumnHeader}\" should be at least 1 char!");
                                break;
                            case ApClasses.EnumDataType.BigInt:
                            case ApClasses.EnumDataType.Int:
                                if (!ApClasses.ApUtilities.ConvToInt(iValue).ToString().Equals(iValue.ToString()))
                                    return new ValidationResult(false, $"\"{Columns[name].ColumnHeader}\" should be an integer!");
                                break;
                            case ApClasses.EnumDataType.Float:
                                if (!ApClasses.ApUtilities.ConvToFloat(iValue).ToString().Equals(iValue.ToString()))
                                    return new ValidationResult(false, $"\"{Columns[name].ColumnHeader}\" should be an float!");
                                break;
                            case ApClasses.EnumDataType.DateTime2:
                                if (!ApClasses.ApUtilities.ConvToDate(iValue).ToString().Equals(iValue.ToString()))
                                    return new ValidationResult(false, $"\"{Columns[name].ColumnHeader}\" should be an TimeStamp!");
                                break;
                        }
                    }
                }
            }
            return ValidationResult.ValidResult;
        }
    }

Diese funktioniert im Prinzip. Jedoch bekomme ich sporadisch falsche Validierungsergebnisse. "bg.TryGetValue(rView, name, out iValue);" liefert false, obwohl im DataRowView der name="ValueIn01" enthalten ist. Hier ist die exportierte DataRowView.

ID;ID_Equipments;ID_Parameterization;ValueIn00;ValueIn01
18;1;1;38000;4

Das Dictionary<string, ApValueMapping> Columns ist immer korrekt gefüllt. Hier zm besseren Verständnis noch das ApValueMapping:


public class ApValueMapping
{
    public string? ColumnHeader { get; set; }
    public EnumDataType DataType { get; set; }

    public ApValueMapping(string columnHeader, EnumDataType dataType)
    {
        ColumnHeader = columnHeader;
        DataType = dataType;
    }
}

Gibt es bei Euch schon Erfahrungen in dieser Richtung?

Erstellt vor 11 Monaten

Hallo Th69, ich bin auf den Weg in den Ski-Urlaub. Sobald ich wieder da bin, versuche ich eine Refernz von "CurrentNodeName" an die child-nodes zu übergeben. Ich danke Dir für die Anregung.

Erstellt vor 11 Monaten

Hallo Th69, danke für Deine Mühe und die schnelle Antwort. Mein Problem ist die Kaskadierung. Events, welche ich versuchte funktionierten nur in der ersten parent-ebene. Also zwischen "node" und den ersten children. Ich habe zwar etwas von blubbernden Events gelesen, denke aber, dies bezieht sich nur auf GUI-Container.

Erstellt vor 11 Monaten

Ich arbeite mich gerade in die wpf-Technologie ein. Die größten Probleme habe ich mit dem Verständnis des Bindings. Ich möchte Inhalte des selektierten Node ausserhalb eines TreeViews nutzen. Um dies zu testen habe ich Cavemans (ich danke Dir) Beispiel angepasst und eine TextBox mit dem CurrentNodeName gebunden:

XAML:

<Window x:Class="ApTest.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:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:ApTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <local:MultiToBrushConverter x:Key="conv"/>
        <ObjectDataProvider x:Key="drives"
                            ObjectType="{x:Type sys:Environment}"
                            MethodName="GetLogicalDrives"/>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <TextBox Text="{Binding CurrentNodeName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }"/>
            <TreeView Name="myTreeView" Grid.Row="0" ItemsSource="{Binding Nodes}">
                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                        <Setter Property="FontWeight" Value="Normal" />
                        <Style.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="FontWeight" Value="ExtraBold" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </TreeView.ItemContainerStyle>
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <TextBlock Text="{Binding Name}" />
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </StackPanel>
    </Grid>
</Window>

MainWindowViewModel:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;

namespace ApTest
{
    internal class MainWindowViewModel : Node
    {

        public ObservableCollection<Node> Nodes { get; set; }

        internal MainWindowViewModel()
        {
            Nodes = new ObservableCollection<Node>
            {
                new Node() { Name = "Node 01" },
                new Node() { Name = "Node 02" },
                new Node() { Name = "Node 03" },
                new Node() { Name = "Node 04" },
                new Node() { Name = "Node 05" },
                new Node() { Name = "Node 06" }
            };

            Nodes[1].Children.Add(new Node() { Name = "Node 02.1" });
            CurrentNodeName = "not assigned";
        }
    }
}

Node:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace ApTest
{
    public class Node : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private string currentNodeName;
        public string CurrentNodeName
        {
            get { return currentNodeName; }
            set {
                currentNodeName = value;
                OnPropertyChanged(nameof(CurrentNodeName));
            }
        }

        public string Name { get; set; }

        public ObservableCollection<Node> Children { get; set; }

        public Node()
        {
            Children = new ObservableCollection<Node>();
        }

        bool isSelected;
        public bool IsSelected { get => isSelected;
            set
            { 
                isSelected = value;
                if (isSelected)
                    CurrentNodeName = Name;
            }
        }
    }
}

Ich verstehe nicht, warum für "CurrentNodeName" nur die Initialisierung "not assigned" angezeigt wird. In der Klasse Node wird "CurrentNodeName" gesetzt. OnPropertyChanged wird aufgerufen. Der aktuelle Wert wird aber nicht abgeholt. Kann mir jemand helfen?

Erstellt vor einem Jahr

Hallo,

manchmal hilft der Zufall. Wenn es passiert melde ich mich.

Danke

Erstellt vor einem Jahr

Das Ausschliessen exklusiver Projekte hat nichts gebracht. Im Anschluss habe ich den versteckten Ordner ".vs" gelöscht: keine Änderung. Da ich zu faul war die verbleibenden Projekte einzeln zu entfernen, habe ich die Solution gesichert, neu angelegt und die Projekte einzeln hinzu gefügt. Ich habe die Solution jedes mal gespeichert, entladen und neu geladen. Es war mühsam, hat sich aber gelohnt. Beide Projektmappen enthalten nun exakt die gleich Anzahl Projekte. Die neue Projektmappe wird schnell, die alte mit der 4 Minuten-Pause geladen.

Beim Vergleich der beiden *.sln - Dateien habe ich nicht wirklich etwas gefunden. Einzig die Reihenfolge der Projekte und die UID des Solution sind unterschiedlich. Aus zeitgründen breche ich nun ab.

Erstellt vor einem Jahr

Hallo gfoidl, danke für die schnelle Antwort.

Ich muss meine Frage etwas korrigieren. Es handelt sich nicht um ein einziges Projekt, sonder um eine Projektmappe mit insgesamt 45 Projekten.

Die Anzahl der Erweiterungen ist sehr übersichtlich. Ich habe sie alle deaktiviert und konnte keinerlei Änderung nach dem Neustart von VS 2019 fest stellen.

Ich werde nun, hier exklusiv genutze, Projekte ausschließen.Vielleicht kann ich es eingrenzen. Ich melde mich wieder.

Erstellt vor einem Jahr

Bei einem einzige Projekt hängt VS 2019 mit der Meldung "Projektmappe wird vorbereitet..". Es wird keine Datei mit einer URL geöffnet! Hat jemand Erfahrung damit? Im ActivityLog findet sich nur folgender Eintrag:

<entry>
    <record>675</record>
    <time>2023/11/14 15:36:29.562</time>
    <type>Information</type>
    <source>MruList</source>
    <description>Did not find item to promote</description>
  </entry>
  <entry>
    <record>676</record>
    <time>2023/11/14 15:40:15.102</time>
    <type>Information</type>
    <source>VisualStudio</source>
    <description>Begin package load [ProviderPackage]</description>
    <guid>{5F2E5E42-4192-4D79-A0D8-1D881E808829}</guid>
  </entry>
Erstellt vor 2 Jahren

Hallo Th69,

danke für die Antwort. Anchor funktioniert in der Basis-Klasse und in den abgeleiteten Klassen.
Ändert man die Größe der abgeleiteten Klasse verschiebt sich der neu hinzugefügte Button sogar außerhalb der GroupBox
(welche hier verkleinert wurde). Ich vermute Microsoft hat hier noch Optimierungsbedarf. Kennt man das aktuelle
Verhalten, kann man ja darauf achten.