Laden...
Avatar #avatar-3126.jpg
Quaneu myCSharp.de - Member
Regensburg Dabei seit 22.10.2008
Benutzerbeschreibung

Forenbeiträge von Quaneu Ingesamt 692 Beiträge

25.03.2024 - 15:45 Uhr

Vielen dank für die Hinweise.

Dann werde ich das Ticket beobachten und wenn es kommt den Code anpassen.

Und das mit dem "stackalloc" ist auch sehr interessant. Auch dafür vielen Dank.

24.03.2024 - 18:25 Uhr

Ich denke ich habe nun die Lösung gefunden, nachdem ich in den Sourcecode angeschaut habe.

Man muss z.B.

Span<Range> ranges = new Range[] { Range.All, Range.All };

verwenden. Dann befüllt er auch beide.

24.03.2024 - 16:57 Uhr

Hallo zusammen,

ich wollte gerade auf einem ReadOnlySpan<char> Split aufrufen. Jedoch bekommen ich immer für count 0 zurück

		ReadOnlySpan<char> toSplit = "Hallo Welt";
		Span<Range> ranges = new Span<Range>();
		var count = toSplit.Split(ranges, ' ');

Leider sehe ich nicht was ich falsch mache. Bei IndexOf gibt er mir für ' ' die richtige Position.

Schöne Grüße und vielen Dank
Permutation

19.10.2023 - 13:53 Uhr

Den Artikel hab ich auf https://stackoverflow.com/a/2583969 auch gefunden. Im ersten Kommentar ist eigentlich auch mein Problem beschrieben. Aber eben leider keine Lösung gesehen. Bzw. gehofft, dass sich in der Zwischenzeit evtl. was geändert hat.

EDIT:
Aber den zweiten Artikel kannte ich noch nicht. Schade, dann ist das eventuell wirklich nicht möglich.

Da ich jedoch die XSD parse kann ich auf solche Dinge reagieren und muss dann "Zwischenobjekte" anlegen analog wie in dem Artikel. Ich hatte gehofft dies vermeiden zu können um Zeit und Speicher zu sparen... 

Aber vielen vielen Dank für Deine Zeit und Hinweise.

19.10.2023 - 13:01 Uhr

Ja genau ich brauch die Reihenfolge, da ich bei der Verarbeitung ja wissen muss was z.B. in <A>...</A> stand.

Ein RoundTrip ist so auch nicht möglich, da er beim Serialisieren dann einen Fehler wirft. Lasse ich es wie es ursprünglich war (mit dem Text Property), dann kommt folgendes raus:

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <A>a</A>
    <B>b</B>
    <C>c</C>
    <A>aa</A>
    <B>bb</B>
    <C>cc</C>abc</Root>

D.h. beide "Lösungen" bringen mich leider nicht weiter, da "Wissen" verloren geht.

Und gibst du das Schema beim Deserialisieren mit (denn dort ist ja Text nicht definiert)?

Nein das gebe ich nicht mit an. Das Textund ItemsProperty sind beide nicht im Schema, werden aber über die Attribute richtig "gesteuert".

19.10.2023 - 11:58 Uhr

Dann kommt liest er den "mixed" Inhalt nicht mehr und kommt z.B. in das Event

        private static void XmlSerializer_UnknownNode(object? sender, XmlNodeEventArgs e)
        {
            throw new NotImplementedException();
        }

mit

Name Wert Typ
e {System.Xml.Serialization.XmlNodeEventArgs} System.Xml.Serialization.XmlNodeEventArgs
LineNumber 2 int
LinePosition 9 int
LocalName "#text" string
Name "#text" string
NamespaceURI "" string
NodeType Text System.Xml.XmlNodeType
▶ ObjectBeingDeserialized {XSDTest.Misc.Choice} object {XSDTest.Misc.Choice}
Text "a" string

EDIT:
mit "#text" hab ich es auch schon probiert.

19.10.2023 - 09:02 Uhr

Hallo zusammen,

ich habe eine Frage zum Serialisieren. Dazu ein kleines Beispiel:

Dies ist das Schema für eine XML Datei die gelesen werden soll:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
	<xsd:complexType abstract="false" mixed="true" name="Choice">
		<xsd:choice maxOccurs="unbounded" minOccurs="0">
			<xsd:element name="A" type="xsd:string"/>
			<xsd:element name="B" type="xsd:string"/>
			<xsd:element name="C" type="xsd:string"/>
		</xsd:choice>
	</xsd:complexType>
	<xsd:element name="Root" type="Choice"/>
</xsd:schema>

Und hier die XML dazu:

<?xml version="1.0" encoding="utf-8"?>
<Root>a<A>a</A>b<B>b</B>c<C>c</C><A>aa</A><B>bb</B><C>cc</C></Root>

Wenn ich nun z.B. mit dem Tool xsd.exe mir Code erzeuge bekomme ich folgendes:

using System.Xml.Serialization;

namespace XSDTest.Misc {
	/// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
    [Serializable()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [XmlRoot("Root", Namespace="", IsNullable=false)]
    public partial class Choice {
        
        /// <remarks/>
        [XmlText(typeof(string))]
        [XmlElement("A", typeof(string))]
        [XmlElement("B", typeof(string))]
        [XmlElement("C", typeof(string))]
        [XmlChoiceIdentifier("ItemsElementName")]
        public string[] Items;
        
        /// <remarks/>
        [XmlElement("ItemsElementName")]
        [XmlIgnore()]
        public ItemsChoiceType[] ItemsElementName;

        ///// <remarks/>
        //[System.Xml.Serialization.XmlTextAttribute()]
        //public string[] Text;
	}
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
    [Serializable()]
    [XmlType(IncludeInSchema=false)]
    public enum ItemsChoiceType {
        /// <remarks/>
        A,
        
        /// <remarks/>
        B,
        
        /// <remarks/>
        C,
    }
}

Ich habe nachträglich das Text Property entfernt und XmlText(typeof(string))]bei Items hinzugefügt, damit ich es "richtig" lesen kann. Nun habe ich aber das Problem, dass ich folgendes Resultat bekomme:

Name Wert Typ
Items {string[9]} string[]
[0] "a" string
[1] "a" string
[2] "b" string
[3] "b" string
[4] "c" string
[5] "c" string
[6] "aa" string
[7] "bb" string
[8] "cc" string
ItemsElementName {XSDTest.Misc.ItemsChoiceType[6]} XSDTest.Misc.ItemsChoiceType[]
[0] A XSDTest.Misc.ItemsChoiceType
[1] B XSDTest.Misc.ItemsChoiceType
[2] C XSDTest.Misc.ItemsChoiceType
[3] A XSDTest.Misc.ItemsChoiceType
[4] B XSDTest.Misc.ItemsChoiceType
[5] C XSDTest.Misc.ItemsChoiceType

Mit diesem Ergebnis kann ich leider nicht viel Anfangen, ich hab schon probiert, den Enum zu erweitern, damit ich bei ItemsElementName die selbe Anzahl bekomme wie bei Items.

z.B.

 [XmlType(IncludeInSchema=false)]
 public enum ItemsChoiceType {
 	 // -------------
	None,
	[System.Xml.Serialization.XmlEnum("#text")]
	Text,
	
 	 // ------------

     /// <remarks/>
     A,
     
     /// <remarks/>
     B,
     
     /// <remarks/>
     C,
 }

Leider hat bisher nichts funktioniert. Daher meine Frage, wie kann ich den Enum ItemsChoiceType so erweitern, dass ItemsElementName auch 9 Einträge hat, oder muss ich es ganz anders machen?

Viele Grüße und vielen Dank
Quaneu

22.06.2020 - 20:30 Uhr

Update:
Ich konnte die Fehler jetzt "lösen", bzw. kommen sie nicht mehr. Aber leider zeigt mir der AssemblyResolver trotzdem noch .Net Framework an 😦

Auf github habe ich die Lösung gefunden. Also wenn ich auf dem "refs&quot; Ordner nur noch die ""netstandard.dll" kommen keine Fehler mehr. Bleibt noch das ".Net Framework" Problem...

21.06.2020 - 11:19 Uhr

Einen ähnlichen Artikel habe ich auch schon gefunden, aber diese Lösung bezieht sich wohl nur auf "Console Application" und nicht auf "Class Library". Aber ich kann es mal probieren.

Edit1:
Also habe jetzt mal die Datei neben die generierte dll geleget, aber leider bringt das auch nichts.

Edit2:
Bild aus ILSpy.

21.06.2020 - 11:04 Uhr

Hier mein Code:


private static CSharpCompilation CreateCompileUnit(string dllName, NamespaceDeclarationSyntax namespaceDeclaration)
{
	CompilationUnitSyntax compileUnit = SyntaxHelper.BuildCompilationUnit(namespaceDeclaration);
	string sourceCodeAsText = compileUnit.NormalizeWhitespace("\t", Environment.NewLine).ToFullString();
	SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCodeAsText);
	SyntaxTree[] trees = { tree };
	CSharpCompilationOptions compilerOptions = new CSharpCompilationOptions(
		OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Debug, platform: Platform.X64);

	var coreDir = Path.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.Location);
	MetadataReference[] reference =
	{
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.CoreLib.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.Xml.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.Uri.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.Extensions.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Xml.ReaderWriter.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Text.RegularExpressions.dll"))
	};
	CSharpCompilation compilation = CSharpCompilation.Create(dllName, trees, reference, compilerOptions);
	return compilation;
}

21.06.2020 - 08:53 Uhr

Ich habe es bisher mit Emit(Stream) aufgerufen. Auch wenn ich es mit den Deinem Vorschlag probiere klappt es leider nicht.

Wenn ich selbst eine .Net Core dll erstelle und in einem anderen Projekt einbinde, muss ich auch nicht die "System.Private.CoreLib" dlls usw. einbinden.
Ich hatte in meinem ersten Beitrag auch erwähnt, dass der Assembly Explorer für die generierte dll .Net Framework anzeigt, was mirfalsch vorkommt. Wenn ich eine .Net Core dll anschaue bekomme ich das nicht. Ich habe mal ein Bild angefügt, damit man sehen kann, was ich meine. Aber ich weiß nicht warum er keine .Net Core dll generiert...

20.06.2020 - 14:59 Uhr

Update:

Selbst wenn ich die generierte dll in ein .Net Standard Projekt einbinde, bekomme ich die Fehler. Ich denke beim bauen der dll geht etwas schief. bzw. mache ich ein Fehler. Aber leider sehe ich den Fehler nicht...

18.06.2020 - 09:24 Uhr

Was meinst Du mit so geschrieben?

Also es darf auch gern .NET Standard sein. Aber beim erstellen der dll, kann ich dies nicht angeben, bzw. habe ich bisher nichts gefunden.

Aber wie geschrieben klappt dies nicht. Die generierte dll lässt sich einbinden, aber ich bekomme immer die Fehler aus meinem ersten Post.

Edit:
Noch mal als Information:
Ich habe ein .Net Core 3.1 Projekt, dass Code generieren soll, bzw. eine dll. Die dll die generiert wurde, binde ich in einen Testprojekt ein, das auch ein .Net Core 3.1 Projekt ist. Sobald ich Code aus der generierten dll verwenden will, zeigt mir VS die besagten Fehler an.

18.06.2020 - 07:43 Uhr

Hallo zusammen,

ich habe mit Roslyn eine dll in einem .Net Core 3.1 Projekt generiert. Dazu erstelle ich eine CSharpCompilation Instanz und rufe auf ihr Emit(...) auf. Dies klappt alles und das EmitResult hat keine Fehler.

Folgende Referenzen benutze ich in dieser dll.


var coreDir = Path.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.Location);
MetadataReference[] reference =
{
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.CoreLib.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.Xml.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.Uri.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.Extensions.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Xml.ReaderWriter.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Text.RegularExpressions.dll"))
};

Wenn ich nun die erstellte dll in meinem Test (auch eine .Net Core 3.1 Projekt) einbinde, bekomme ich folgende Fehler, für Code aus dieser dll.

Fehlermeldung:
Error CS0012 The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
Error CS0012 The type 'Stream' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.

Ich verstehe nicht was ich falsch mache. Mein Ziel ist es, das die dll auch ein .Net Core oder .Net Standard Projekt ist. Leider habe ich dazu keine Einstellungen gefunden, bzw. gelesen das der Output anscheinend imme ein .Net Standard Projekt sein soll. Wenn ich jedoch im Assembly Explorer die dll anschaue steht dabei, "... (x64, .Net Framework v4.7.2, Debug).

Ich hoffe mir kann wer einen Hinweis geben, was ich falsch mache bzw. vergessen habe.

Schöne Grüße
Quaneu

11.06.2020 - 11:56 Uhr

Und müßte xml:space="preserve" nicht innerhalb der XML-Datei stehen?

Du hast vollkommen recht... sorry. Damit bekomme ich dann auch IgnoreWhitespace = true einen SignificantWhitespace Node. Jetzt passt auch wieder alles.

Du erhältst also Whitespace innerhalb des Text-Node?

Ja die bekomme ich.

WhitesapceHandling steht bei dir aber auf All (default)?

Also ich setzte nichts. Ich benutze ja XmlReader.Create mit den Settings.

Vielen vielen Dank für deine Hilfe 👍

11.06.2020 - 10:54 Uhr

In der Doku zu Ignorewhitespace steht folgendes

Leerraum, der nicht als signifikant betrachtet wird, umfasst Leerzeichen, Tabstopps und leere Zeilen, mit denen das Markup für eine bessere Lesbarkeit festgelegt wird. Ein Beispiel hierfür ist Leerraum im Element Inhalt.

Diese Eigenschafts Einstellung wirkt sich nicht auf Leerraum zwischen Markup in einem gemischten Inhalts Modus oder Leerraum aus, der innerhalb des Gültigkeits Bereichs eines xml:space='preserve' Attributs auftritt.

Daher dachte ich ich kann es auf true lassen.

Selbst wenn ich im Schema folgendes schreibe


<xs:element name="Property_9" type="ComplexType_2" xml:space="preserve"/>

Bekomme ich nur bei Ignorewhitespace = false einen Whitespace Node.

Dies widerspricht sich doch mit der Dokumentation, oder?

Edit: Zu deiner Frage:
Also ich bekomme folgendes:
"
text text2
text3 "

als Text und der Rest verhält sich wie bei meinem Beispiel.

11.06.2020 - 09:47 Uhr

Hallo zusammen,

ich versuche gerade eine XML Datei mit dem XmlReader einzulesen. Dabei bin ich über folgendes Problem gestolpert.

Den XmlReader lege ich wie folgt an


XmlReaderSettings xmlReaderSettings = new XmlReaderSettings{IgnoreComments = true, IgnoreProcessingInstructions = true, IgnoreWhitespace = true};
xmlReaderSettings.ValidationType = ValidationType.Schema;
xmlReaderSettings.ValidationEventHandler += validationEventHandler;
using (XmlReader xmlReader = XmlReader.Create(stream, xmlReaderSettings))
{
	return Reader.ReadContent(xmlReader);
}

Das Element das Probleme verursacht sieht im Schema wie folgt aus


<xs:complexType name="ComplexType_2" mixed="true">
	<xs:sequence>
		<xs:element name="ComplexType_2_Property_1" type="xs:string"/>
	</xs:sequence>
</xs:complexType>

Und in der XML wie folgt


	<Property_9>
		text<ComplexType_2_Property_1>ComplexType_2_Property_11</ComplexType_2_Property_1>     
	</Property_9>

Wenn ich nun mit dem Reader dieses Element lesen will bekomme ich nie den Zeilenumbruch und "\t" nach </ComplexType_2_Property_1> obwohl es ja mixed ist. Wenn ich IgnoreWhitespace auf false setze bekomme ich es zwar als Whitespace Node aber nicht als SignificantWhitespace Node. Leider verstehe ich nicht, was ich falsch mache bzw. wo mein Denkfehler liegt.

Der Code zum Lesen sieht wie folgt aus (ist generiert):


public static ComplexType_2_T Read_ComplexType_2_T(XmlReader xmlReader)
{
	var instance = new ComplexType_2_T();
	int position = -1;
	while (xmlReader.Read())
	{
		SkipRead:
		switch (xmlReader.NodeType)
		{
			case XmlNodeType.Element:
				switch (xmlReader.Name)
				{
					case "ComplexType_2_Property_1":
						if (position == 0)
							return instance;
						instance.Add_ComplexType_2_Property_1_P(xmlReader.ReadElementString());
						position = 0;
						goto SkipRead;
					default:
						return instance;
				}

			case XmlNodeType.Text:
				instance.Add_MixedContent(xmlReader.Value);
				break;

			case XmlNodeType.Whitespace:
				break;
			case XmlNodeType.SignificantWhitespace:
				break;
		}
	}

	return instance;
}

Vielen Dank schon mal für die Hinweise

Schöne Grüße
Quaneu

28.01.2020 - 10:08 Uhr

Ich habe jetzt eine Lösung gefunden 😃.

Ich habe nun eine Klasse die für das Gruppieren zuständig ist. Diese stellt ein Property Collection bereit, an die sich das Grid binden kann. Wenn man nun gruppieren will, erstelle ich eine neue ListCollectionView in einem Task und gruppiere in diesem. Danach wird diese dem Property Collection hinzugefügt. Klappt bisher ganz gut 😃

Hatte wolh ein Brett vorm Kopf, da ich Anfangs die Collection nur einmal (OneTime) binden wollte...

Schöne Grüße
Quanue

27.01.2020 - 13:10 Uhr

Hello Schleenz1984,

here is an example from RichTextBox


public BasicRichTextBoxWithContentExample()
        {
            StackPanel myStackPanel = new StackPanel();

            // Create a FlowDocument to contain content for the RichTextBox.
            FlowDocument myFlowDoc = new FlowDocument();

            // Create a Run of plain text and some bold text.
            Run myRun = new Run("This is flow content and you can ");
            Bold myBold = new Bold(new Run("edit me!"));

            // Create a paragraph and add the Run and Bold to it.
            Paragraph myParagraph = new Paragraph();
            myParagraph.Inlines.Add(myRun);
            myParagraph.Inlines.Add(myBold);

            // Add the paragraph to the FlowDocument.
            myFlowDoc.Blocks.Add(myParagraph);

            RichTextBox myRichTextBox = new RichTextBox();

            // Add initial content to the RichTextBox.
            myRichTextBox.Document = myFlowDoc;
            
            myStackPanel.Children.Add(myRichTextBox);
            this.Content = myStackPanel;
        }

Best regards,
Quaneu

26.01.2020 - 21:00 Uhr

Hallo zusammen,

ich bin gerade dabei Daten in einem DatGrid zu gruppieren. Dazu benutze ich eine ListCollectionView und befülle die GroupDescriptions.

z.B.


		public bool GroupByVariableName
		{
			get => _groupByVariableName;
			set
			{
				_groupByVariableName = value;
				GroupDescriptions.Clear();
				if (_groupByVariableName)
				{
					GroupDescriptions.Add(new PropertyGroupDescription("Name"));
				}
				OnPropertyChanged(new PropertyChangedEventArgs(nameof(GroupByVariableName)));
			}
		}

Das Problem ist, dass der Aufruf "Add" auf GroupDescriptions sehr lange brauchen kann. Dies hat zur Folge, dass das GUI einfriert. Um dies zu verhindern, würde ich gern diesen Aufruf async auszuführen. Jedoch geht dies leider nicht, wenn die ListCollectionView schon gebunden ist (Thread Probleme...).

Daher meine Frage kennt ihr einen sauberen Weg GroupDescriptions eine PropertyGroupDescription hinzuzufügen ohne das das GUI einfriert?

Schöne Grüße
Quaneu

P.S. An VirtualizingPanel.IsVirtualizingWhenGrouping habe ich schon gedacht 😃 Es liegt wirklich nur am Add(...)

28.03.2019 - 17:04 Uhr

Es gibt eine DLL "X" in ihr sind zwei DLLs embedded. Wenn diese gebraucht werden, "entpacke" ich diese DLLs.
Dies wird deshalb gemacht da die "X" DLL beim Programmstart geupdatet werden kann und ich nicht n-DLLs kopieren will, sondern nur eine. Damit stelle ich auch sicher, dass das gesamte Packet zusammen passt.

28.03.2019 - 16:21 Uhr

Danke für die Info.

Wenn es hier ein Problem gibt, dann hast Du wahrscheinlich was falsch gemacht.

Wie gesagt, dass Problem sind z.B. alle statischen Klassen, die von WPF initialisiert werden (z.B. Application.Current). Diese sind in der AppDomain alle nicht initialisiert.

Warum Du "DLLs löschen willst, wenn sie ihre Arbeit erledigt haben" erschließt sich mir nicht.

Da ich die DLLs entpacke wollte ich sie auch wieder aufräumen. D.h. der Ordner soll nach dem Durchlauf so sein wie davor.

28.03.2019 - 09:41 Uhr

Hallo zusammen,

ich würde gerne wissen ob bzw. wie man folgendes Problem lösen könnte.

Ich habe eine exe (WPF) die eine DLL verwendet, diese kann vor der ersten Benutzung der DLL geupdatet werden, wenn die exe eine neuere Version findet. Die DLL wiederrum benutzt zwei weitere DLLs (eine ist Mixed Mode) die sie "entpackt" und verwendet (es wird dagegen implementiert).
Ich würde jedoch diese zwei DLLs wieder löschen wollen, wenn sie ihre Arbeit getan haben. Und hier finde ich einfach keinen Weg.

Ich habe es schon mit einer eigenen AppDomain probiert, da man Assemblies nicht einzeln entladen kann, jedoch kam es hier immer wieder zu Problemen... z.B. Application.Current ==null.

Gibt es hier auch eine andere Möglichkeit bzw. Lösungsansatz?

Schöne Grüße
Quaneu

26.01.2019 - 18:06 Uhr

Ich hab das Problem gefunden. Es lag nicht an der Architektur und wohl auch nicht am async / await, bzw. nur indirekt.

Hier ein Beispiel Code (hier habe ich auf Architektur verzichtet 😄)


<Window x:Class="Sample.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:Sample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
		<Grid.RowDefinitions>
			<RowDefinition Height="*"/>
			<RowDefinition Height="Auto"/>
		</Grid.RowDefinitions>
		<ListBox Grid.Row="0" ItemsSource="{Binding Names, Mode=OneTime}"/>
		<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
			<Button HorizontalAlignment="Right" Content="WorkAsync" Click="Button_Click" Margin="2"/>
			<Button HorizontalAlignment="Right" Content="AddSingleName" Click="Button_Click_1" Margin="2"/>
		</StackPanel>
	</Grid>
</Window>


using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;

namespace Sample
{
	public partial class MainWindow : Window
	{
		private readonly object _itemsLock;
		public MainWindow()
		{
			_itemsLock = new object();
			Names = new ObservableCollection<string>();	
			BindingOperations.EnableCollectionSynchronization(Names, _itemsLock);
			DataContext = this;
			InitializeComponent();
			Names.CollectionChanged += Names_CollectionChanged;
		}

		private void Names_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
		{
			var listCollectionView = ((ListCollectionView)CollectionViewSource.GetDefaultView(Names));
		}

		public ObservableCollection<string> Names { get; }

		private async void Button_Click(object sender, RoutedEventArgs e)
		{
			await Task.Run(() => HeavyMethod());
		}

		internal void HeavyMethod()
		{
			for (int i = 0; i < 3; i++)
			{
				Thread.Sleep(1000);
				AddName($"Name_{i}");
			}
		}

		private void Button_Click_1(object sender, RoutedEventArgs e)
		{
			AddName("SingleName");
		}

		private void AddName(string name)
		{
			lock (_itemsLock)
			{
				Names.Add(name);
			}
		}
	}
}

Drückt man erst auf WorkAsync und danach auf AddSingleName kommt es zur Exception. WorkAsync kann man aber beliebig oft drücken.
Das Problem macht folgende Zeile


var listCollectionView = ((ListCollectionView)CollectionViewSource.GetDefaultView(Names));

Ohne diese läuft es immer... Leider verstehe ich es aber immer noch nicht 🤔

Schöne Grüße
Quaneu

25.01.2019 - 21:26 Uhr

Ich habe jetzt eine Lösung gefunden jedoch würde ich gern verstehen wie dieser Fehler zustande kommt.

Meine Lösung:
Wenn man diese AsyncObservableCollection benutzt
http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/

und


BindingOperations.EnableCollectionSynchronization(LogEntries, _itemsLock);

entfernt klappt es wie erwartet. Aber wie schon gesagt, wenn jemand weiß woran es liegt wäre ich sehr dankbar.

Schöne Grüße
Quaneu

25.01.2019 - 18:02 Uhr

Hallo MrSparkle,

das sieht vielleicht nur so aus. Es ist (bzw. sollte) nach MVVM gebaut sein.
Es gibt die UI, dann meine ViewModels und meine DatenObjekte. Man kann hier ischer noch einiges schönes machen, jedoch denke ich, dass dies nicht mein Problem verursacht. Aber ich werde nochmals einen Blick drauf werfen. Daher Danke für den Hinweis 😃

Schöne Grüße
Quaneu

25.01.2019 - 16:35 Uhr

Hallo Abt,

vielen Dank für deine Hinweise. Task.Run und async void habe ich gleich mal korrigert.

Könntest Du mir vielleicht sagen, was falsch implementiert ist? Wenn ich in meinem Beispiel nämlich ConfigureAwait(false) einbaue bekomme ich schon Fehler beim "ersten" Update.

Schöne Grüße
Quaneu

25.01.2019 - 16:06 Uhr

Hallo zusammen,

ich habe ein Problem mit einer ObservableCollection, die aus einem anderen Thread aktualisiert werden soll. Hierzu verwende ich BindingOperations.EnableCollectionSynchronization.


private readonly object _itemsLock = new object();
public Logger(string logPath)
{
	LogPath = logPath;
	LogEntries = new ObservableCollection<LogEntry>();
	BindingOperations.EnableCollectionSynchronization(LogEntries, _itemsLock);
}

public void AddInfo(string message)
{
	lock (_itemsLock)
	{
		Log(message, LogConstants.Info);
	}
}

Diese Klasse wird im MainThread angelegt.

Das Aktualiseren in einem anderen Thread klappt. Jedoch wirft jeder Update, der danach stattfindet eine Exception, wenn dieser nicht in einem anderen Thread stattfindet.

Fehlermeldung:
System.NotSupportedException: 'Von diesem CollectionView-Typ werden keine Änderungen der "SourceCollection" unterstützt, wenn diese nicht von einem Dispatcher-Thread aus erfolgen.'

Das Updaten mache ich wie folgt:


private void ExecuteOpenPackage(object packageFile)
{
	OpenPackage(packageFile as string);
}

private async void OpenPackage(string packageFile)
{
	var openPackageResult = await OpenPackageAsync(Logger, packageFile);
}

private static Task<OpenPackageResult> OpenPackageAsync(Logger logger, string packageFile)
{
	return Task<OpenPackageResult>.Factory.StartNew(() =>
	{
		// Lange Operation
		logger.AddInfo("test");
		return null;
	});
}

Kann mir jemand sagen was ich falsch mache? Sobald ich eben den Task starte kann ich die Collection nicht mehr ohne Task updaten.

Schöne Grüße und vielen Dank
Quaneu

12.10.2018 - 08:45 Uhr

Hallo herbivore,

vielen Dank für deine Hilfe.

Mein Beispiel sollte folgenden Fall abdecken:

Ein Wort muss aus den Bestandteilen A,B und C bestehen, wobei man nur ein oder zwei Bestandteile wählen darf, dies aber beliebig oft. Jedoch mit der weiteren Einschränkung, dass die Reihenfolge beachtet werden soll. D.h. wenn ich 2 Bestandteile wähle, darf z.B. kein Element aus B vor denen aus A kommen usw.

Das bauen des Regexes ist nicht das Hauptproblem, sondern eher der Regex selbst. Wenn es nur diese Möglichkeit gibt, muss ich testen ob dies noch möglich ist, da z.B. A aus 6000 Wörtern besteht B hat mind. genau soviel usw.. dadurch würde der Regex extrem "lang" werden. Aber ich probier es mal im Kleinen.

Schöne Grüße und vielen Dank
Quaneu

P.S. Danke für dein Regex-Lab ist wirklich super und hat mir schon oft sehr weiter geholfen👍

11.10.2018 - 13:00 Uhr

Hallo zusammen,

ich würde gern eine Art Choice in Regex formulieren. Leider schaffe ich dies nicht 100%.

Z.B. Soll der Name aus A, B oder C bestehen, wobei A, B oder C wieder ein Regex sein kann. Wenn es nur einen Treffer geben soll, also Choice min=1 max=1 ist, habe ich eine Lösung "(A+|B+|C+)".

Komplizierter wird es wenn max z.B. 2 ist und dieser öfter treffen soll.
Hier ein konkreteres Beispiel:
A = [a|b|c], B = [d|e|f], C= [g|h|i] und der Name soll "adgbeh" sein.
Wenn ich nun folgenden Regex benutzte "((([a|b|c])+|[d|e|f])+|([g|h|i])+){1,2})*" sagt mir dieser, dass der Name gültig ist, aber meine Captures sind nicht so, wie ich sie brauche. In diesem Fall "ad gb eh". Das Problem dabei ist jedoch "gb". Es soll nämlich die Reihenfolge der Elemente berücksichtigt werden und g kommt nach dem b. Mein Ziel ist es, folgende Captures zu erhalten "ad g be h".

Ich habe es schon mit Lookaround probiert, jedoch ohne Erfolg.

Hätte jemand eine Idee, wie ich dieses umsetzen kann?

Schöne Grüße
Quaneu

11.10.2018 - 11:04 Uhr

Entschuldige bitte meine späte Antwort. Aber leider war es mir nicht möglich, früher zu antworten.

Danke für deinen Hinweis. Dies klappt jetzt ganz gut.

05.09.2018 - 11:05 Uhr

Hallo zusammen,

ich will mit einem Regex prüfen, ob z.B. aus drei Gruppen mindestens eine trifft.

Hier ist ein Beispiel: "1([abc]* | [def]* | [ghi]*){1}2"

D.h. ich würde gerne prüfen ob [abc], [def] oder [ghi] mindestens einmal trifft. Dies klappt mit diesem Regex auch fast, jedoch trifft er auch "12" und dies soll verboten sein.

Wie kann man dies über Regex abbilden?

Schöne Grüße und vielen Dank
Quaneu

07.07.2018 - 09:38 Uhr

Hallo herbivore,

vielen vielen Dank für deine Antwort 🙂. Du hast Recht. Ich hab mir gestern zwar den Match bzw. die Groups in dem Match immer wieder angeschaut, aber die Captures nicht mehr, da die Group "2" als Value nur "c" hat. Kann es sein das dies auch "spezielles" Feature des .Net Regex ist?

Schöne Grüße und nochmals vielen Dank
Gennaro

P.S.
Dein Tool ist wirklich super 👍 👍 👍 kommt jetzt immer zum Einsatz!

06.07.2018 - 19:51 Uhr

Hallo zusammen,

ich habe eine Frage zu Regex in Bezug auf Matches.

Wenn ich folgenden Namen "abc" und diesen mit dem Regex "^(?<1>[a|b])*(?<2>[b|c]){2,}$" prüfen will. Dann bekomme ich als Ergebnis ein Match, jedoch mit folgender Aussage:


                           Start  Length
Match 1:	abc	     0	     3
Group "1":	 a	     0	     1
Group "2":	 c	     2	     1

Das "b" geht verloren bzw. wird nicht als Treffer in Group "2" angezeigt. Ich bräuchte jedoch als Resultat folgendes:


                           Start  Length
Match 1:	abc	     0	     3
Group "1":	 a	     0	     1
Group "2":	 b	     1	     1
Group "2":	 c	     2	     1

Was nicht reichen würde, ist


                           Start  Length
Match 1:	abc	     0	     3
Group "1":	 a	     0	     1
Group "2":	 bc	     1	     2

Weiß jemand wie ich den Regex dazu bringe, mir dies auszugeben?

Vielen Dank und schöne Grüße
Quaneu

14.04.2018 - 13:29 Uhr

Entschuldige bitte. Ja ist ein Integrationstest.

Ich hab es deshalb so gelassen, da ja mit Hilfe von MsTest auch automatisch aufgeräumt wird usw.. Wenn ich die Dateien in ein anderes Verzeichnis schreibe, muss ich das alles machen.

Aber Du hast mich gerade auf eine Idee gebracht. Die exe liegt in dem TestsResults Ordner, d.h. ich kann die Angaben für die Dateien relativ setzten, d.h. somit taucht das Datum nicht mehr im Pfad auf.

VIELEN VIELEN DANK.

Manchmal hilft es einfach, drüber zu reden 😃

14.04.2018 - 13:09 Uhr

Kein Problem.

Also der Test ruft mein Tool auf, dass eine Datei in eine andere Umwandelt und prüft ob die geschriebene Datei gültig ist. Das Resultat der Umwandlung wird in TestResults... geschrieben und anschließend eben gegen eine Referenzdatei verglichen. Dadurch, dass eben wie unten erwähnt, in den Pfaden ein Datum vorkommt (als Kommentar in der geschrieben Datei), kann es keine gültige Referenzdatei geben, bzw. schlägt der Test an.

14.04.2018 - 12:48 Uhr

Ich schreibe eine Datei, in der z.B. folgendes steht
// LogPath: C:\Users\ToolName\TestResults\Deploy_User 2018-04-14 11_43_06\Out\Outputs_AddressImportFiles\Diab_5.8.0.txt

Dadurch, das 2018-04-14 11_43_06 im Pfad vorkommt, kann ich keine Referenzdatei erstellen, da sich das Datum je immer ändert, bzw. schlägt eben der Test fehl.

aber vielen Dank für deine Hinweise.

14.04.2018 - 12:27 Uhr

Also bei mir sieht er immer so aus: Deploy_<User> <Datum>

Das Problem ist, dass ich Dateien schreibe, in denen als Kommentar z.B. steht, wie der Log oder der Destination Pfad lautet. In diesen ist somit auch das Datum. Da ich die geschrieben Dateien gegen Referenzdateien prüfe (binär) bekomme ich eben falsche Resultate.

Ich könnte natürlich "seams" einbauen, aber dann teste ich schon wieder "weniger.

14.04.2018 - 12:01 Uhr

Hallo zusammen,

ich würde gerne den Namen der Folder in TestResults ändern.
Bisher werden diese ja immer unter "...\TestResults\Deploy_<User> <Datum>" abgelegt. ich würde gerne das Datum weglassen, da dies in manchen Tests Probleme macht.

In der Local.runsettings habe ich nur Möglichkeit ResultsDirectory zu beeinflussen, aber dies Hilft mir nicht weiter.

Hat jemand eine Idee wie man das Datum weglassen kann? Ich benutzt VS2017 mit MsTest und/ oder ReSharper.

Schöne Grüße und vielen Dank
Quaneu

18.11.2017 - 14:08 Uhr

VIELEN VIELEN DANK.
Mit IsSharedSizeScope klappt es wunderbar. Jetzt ist es schöner als ursprünglich angedacht 👍 👍 👍

18.11.2017 - 13:44 Uhr

Und nochmals vielen Dank 😃

Ich probiere es gerade mit IsSharedSizeScope. Wenn dies klappt, wäre es für mich die schönste Lösung. Aber ich habe ja jetzt noch ein paar Alternative 😉

18.11.2017 - 11:00 Uhr

Hallo Palladin007,

vielen Dank für deine Hinweise. Ich werde es gleich mal ausprobieren
Das man es über CodeBehind lösen muss, war mir auch bewusst. Ich meinte mit XAML eher, dass ich in diesem den Content bereitstelle, um den das Grid erweitert werden soll. Z.B


<misc:BasicInformationUserControl.FurtherContent>
	<ItemsControl>
		<TextBox Text="A" Grid.Row="0" Grid.Column="0"/>
		<TextBox Text="B" Grid.Row="0" Grid.Column="1"/>
	</ItemsControl>
</misc:BasicInformationUserControl.FurtherContent>

Leider bekomme ich eben mit diesem Beispiel PropertyChangedCallback von FurtherContent immer ein ItemsControl ohne Items...

Schöne Grüße
Quaneu

18.11.2017 - 08:34 Uhr

Hallo zusammen,

eine Frage kommt selten alleine...

Ich probiere schon seid Stunden folgendes Problem zu lösen. Ich habe ein UserControl, in dem ein Grid definiert ist mit z.B. 3 Zeilen und 2 Spalten. Nun würde ich an den Stellen, an dem ich das UserControl benutze das Grid so erweitern, dass ich Zeilen hinzufügen kann, die dann die selben Spaltenbreiten haben, wie das Grid im UserControl. Leider finde ich keine Möglichkeit dies umzusetzen.
Ich habe es schon mit einem DependencyProperty "FurtherContent" probiert, das ich setzten kann und im PropertyChangedCallback das Grid dynamisch erweitere.
Doch leider klappt dies nicht. Wenn z.B. "FurtherContent" vom Typ Grid ist so kommt im PropertyChangedCallback ein Grid an, dass nie Children hat, obwohl im XAML welche definiert sind.

Schöne Grüße
Quaneu

18.11.2017 - 08:08 Uhr

Hallo Th69,

vielen Dank für deine Links. Jetzt ist mir einiges klarer.

Schöne Grüße
Quaneu

17.11.2017 - 15:53 Uhr

Hallo zusammen,

ich habe ein "eigenes" Control, dass von GroupBox ableitet.


<GroupBox x:Class="Test.OwnGroupBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<GroupBox.Style>
		<Style TargetType="{x:Type GroupBox}">
			<Setter Property="Margin" Value="2"/>
		</Style>
	</GroupBox.Style>
</GroupBox>

Wenn ich nun diese GroupBox wie folgt benutze


<UserControl x:Class="Test.BasicInformationUserControl"
							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:controls="clr-namespace:Test"
							mc:Ignorable="d" x:Name="_basicInformationUserControl"
							x:Uid="BasicInformationUserControl">
	<controls:OwnGroupBox Header="General" x:Uid="GeneralGroupBox">
	                <TextBlock Text="Status" x:Name="xxx"/>
			<ContentPresenter Content="{Binding Height, ElementName=_basicInformationUserControl}"/>
	</controls:OwnGroupBox>
</UserControl>

bekomme ich diesen Fehler> Fehlermeldung:

Cannot set Name attribute value 'xxx' on element 'TextBlock'. 'TextBlock' is under the scope of element 'OwnGroupBox', which already had a name registered when it was defined in another scope.

Und das Binding im ContentPresenter geht auch nicht. Ersetze ich nun controls:OwnGroupBox durch GroupBox, bekomme ich keinen Fehler mehr und das Binding klappt.

Leider verstehe ich nicht wieso eine Ableitung dies zur Folge hat. Hätte jemand eine Idee, warum dies so ist.

Viele Grüße
Quanue

11.06.2017 - 21:15 Uhr

Hallo MrSparkle,

mit Validierung ist hier z.B. gemeint, ob der User etwas an der Eingabemaske geändert hat. Wenn er etwas geändert hat, soll eine Abfrage kommen, ob er speichern oder die Eingaben verwerfen will. Geht jedoch beim speichern etwas schief, soll kein neuer Knoten (hier TreeViewitem) selektiert werden.

Im ViewModel für meine TreeViewitems geht es leider nicht, bzw. wüsste ich nicht wie. Daher feuert jedes TreeViewitemViewModel ein Event wenn es selektiert wird und ein Controller hört auf diese und macht bisher auch die Validierung. Mein Problem ist nur das Unterbinden eines TreeViewItems Wechsels.

Schöne Grüße
Quaneu

10.06.2017 - 20:05 Uhr

Hallo zusammen,

ich habe folgendes Problem.

Wenn in einem TreeView ein anderer Knoten selektiert wird, soll eine Überprüfung stattfinden, die eventuell eine Änderung des Knotens unterbinden soll. Dazu sei gesagt, dass wenn die Überprüfung eine Änderung untersagt, eine MessageBox auf geht, in der der User abspeichern, oder die Änderungen verwerfen kann.

Ich habe es schon mit einem PreviewMouseLeftButtonDownCommandProperty Behavior probiert, dass ich auf dem TreeView registriere.
Jedoch habe ich hier ein merkwürdiges Verhalten festgestellt. Ich setzt, je nachdem ob der User speichern will oder nicht, e.Handled auf false oder true (im PreviewMouseLeftButtonDown Event).
Dies funktioniert leider nur, wenn keine MessageBox auf geht. Geht eine auf, ist es so, als ob e.Handled immer auf false gesetzt wird. Leider verstehe ich nicht wieso dies so ist...

Für andere Lösungen oder einer Erklärung der besagten Verhaltens, wäre ich sehr dankbar.

Schöne Grüße
Quaneu

26.07.2016 - 21:48 Uhr

Ich habe jetzt mal alles relativ positioniert, aber eben noch mit Overflow. Leider scheint dies den Browser zu "iterieren", d.h. das Springen klappt nicht mehr, wenn ich Overflow auf Auto setze.

Weiß jemand wie man overflow benutzt und das Springen im Browser ermöglicht?

26.07.2016 - 15:15 Uhr

Ich dachte da ich alles mit % bzw. vh benutzte sollte es keine Probleme geben... Da ich aber erst seid kurzem Html mache, wurde ich wohl heute eines Besseren belehrt.
Wenn jedoch noch jemand einen Hinweis habe wie ich mein Problem anders lösen kann, bin ich für alles aufgeschlossen 😉

Und nochmals Danke für die Hilfe 👍

26.07.2016 - 14:44 Uhr

Ich habe den Übeltäter gefunden:


        #_9359f5c9607546909d0a55812fd07445 {
            position: fixed;
            top: 2%;
            left: 20%;
            overflow-x: auto;
            height: 95vh;
            width: 80%;
            background: #DAECF5;
            border-top-left-radius: 5px;
            border-bottom-left-radius: 5px;
        }

Wenn man position: fixed und overflow-x: auto wegnimmt, klappt es...
Jetzt frag ich mich aber, wie Löse ich diesen Konflikt...