Laden...

Forenbeiträge von ErfinderDesRades Ingesamt 5.299 Beiträge

01.01.2021 - 16:54 Uhr

nein, da muss man nix selber proggen.
Die anderen drei spalten müssen einfach auch ComboboxColumns sein - nur je mit anderm DisplayMember.

Hmm - naja.
Wie's aussieht verwendest du kein typisiertes Dataset.
Das ist dann alles ziemlich chaotisch, und du musst vielleicht doch so rumwursteln.
Also wenn du mal sehen willst, wie es auch gehen kann gugge
vier Views-Videos
Der Code dazu ist aber vb - das ist aber nicht wesentlich daran. Wichtig ist, die Konzepte zu verstehen, und wie die Designer zu nutzen sind.

29.12.2020 - 14:12 Uhr

uff - da bin ich draussen - Knapsack hoch 3!
Bin grade erst dabei Knapsack überhaupt zu kapieren - es ist nicht einfach nur Backtracking.
Tatsächlich ist der Standard-Algo zum Matrix-Füllen nichtmal rekursiv, und auch das anschliessende Auswerten derselben nicht.
Also ich weiss nicht, ob die bei Wikipedia einen richtigen Begriff von Backtracking haben, oder ich - bei mir ist Backtracking rekursiv.
Hier auf myCsharp finde ich auch nix wirkliches zum Knapsack, nur Beiträge, in denen behauptet wird, das sei erledigt, und im besten Falle noch: man solle da und da gucken...
Oft aber auch nur: Man solle selber gucken 8o (ohne da und da)

Hier fand ich schliesslich den Standard-Algo: https://www.programmingalgorithms.com/algorithm/knapsack-problem/
Allerdings ohne die Auswertung der Matrix - das fund ich hier: https://www.proggen.org/doku.php?id=algo:knapsack
Und auch eine mir verständliche Erklärung. Aber die haben eine rekursive Implementierung - vmtl. bisserl suboptimal.
/OT

Ich glaub garnet, dass man da was paralellisieren kann. Bei Knapsack hängt eine Teil-Lösung doch ab von zuvor gefundenen Teil-Lösungen - das kann man doch garnet nebeneinander her-wursteln lassen.

28.12.2020 - 21:28 Uhr

Tja, ich würds gerne probieren, deinen Code zu verbessern - etwa durch Backtracking.
Allein ich sehe ihn nicht...?

28.12.2020 - 15:32 Uhr

Zum Thema Rucksack: Von Wikipedias Erklärung verstehe ich nur iwas mit Backtracking.
Läuft "dynamische Programmierung" etwa auf folgendes hinaus?

Rekursiv alle Kombinationen durchgehen und dabei die (bisher) beste merken.
Bei der rekursiven Vertiefung immer abbrechen, wenn der aktuelle Wert bereits schlechter ist als der bislang gefundene beste Wert ?

das käme mir ziemlich trivial vor, dass man nicht weiter rumprobiert, wenn man eh schon aussm Limit ist.
Ist das, was der berühmte Bellmann meinte?

Ich versteh auch nicht den Wiki-Pseudo-Code mit den verschachtelten For-Schleifen. Sollte ich das richtig verstanden haben, sehe ich da eigentlich keine andere Lösung als eine Rekursive (oder evtl. noch eine, die Rekursion iterativ emuliert, etwa mit einem Stack)

Edit: Ups - Sorry - da kam nun ein Post dazwischen

28.12.2020 - 11:11 Uhr

Wie würde man mit BinarySearch eine Einfüge-Position ermitteln können? Ich dachte, so finde ich nur die Position eines vorhandenen Elementes. Tja, so kann man sich irren.
Ich hab dir doch gesagt, dass List<T> BinarSearch kann.
wie das geht, habich damals auch im Internet rausgefunden. Und dort gelernt, dass bei nicht-Match das Bit-Complement der EinfügePosition returnt wird.

aber wie gesagt: Wenn du wirklich mit nur 10 Elementen unterwegs bist (oder 100, oder 1000), dann lass den Quatsch, und insbesondere iwelche Parallelitäts-Experimente.

schnapp dir Collection<T> und bau erstmal eine funktionierende LimitedSortedList<T>.
Optimieren soll man immer!! als allerletztes machen.

28.12.2020 - 10:38 Uhr

Hi!
Ich arbeite ganz viel mit Datasets - typisierten allerdings. Ich finde, das hat deutliche Vorteile - zB ein an eine DataTable gebundenes DatagridView kann out-of-the-box nach beliebigen Spalten sortieren (bei vielen Datensätzen oft hilfreich).
(ORM - weiss ich garnet, ob die dann neue Abfragen auslösen müssen, oder wie man bei denen Sortierung umsetzt - jedenfalls nicht out-of-box)

Ich wundere mich, wenn du sagst:

Die DataTable benutze ich da ich es schneller geht, die Tabelle von der ich lese hat 4GB, die Daten die ich filter haben dann noch ca. 2GB. Du willst doch nicht etwa ein DatagridView anzeigen mit 2GB Daten?

Wie kann ich in Verbindung mit einer BindingSource darauf zugreifen? Beim typisierten Dataset brauchst du keine eigenen Datenklassen zu erstellen, das macht der Dataset-Designer.
auf eine typisierte Row greift man so zu:


        void changeSelectedCustomerBtn_Click(object sender, EventArgs e)
        {
            var rwCustomer = (CustomerRow)((DataRowView)customersBindingSource.Current).Row;// Get the current Customer from the BindingSource.  
            rwCustomer.CustomerName = "Tailspin Toys";
            rwCustomer.PhoneNumber = "(708)555-0150";
        }

        void changeFirstCustomerBtn_Click(object sender, EventArgs e)
        {
            var rwCustomer = (CustomerRow)((DataRowView)customersBindingSource[0]).Row;// Get the first Customer from the BindingSource.  
            rwCustomer.CustomerName = "Tailspin Toys";
            rwCustomer.PhoneNumber = "(708)555-0150";
        }

Mehr brauchts nicht - nichtmal Kommentare - wenn zB die Buttons korrekt benamt sind.
Sind sie aber bei dir nicht, und deine Kommentation ist scheints veraltet, und trifft unzutreffende Aussagen

28.12.2020 - 10:13 Uhr

Ich hab mich vor langem mal an so wiederverwertbaren Forms versucht - unds dann gelassen.

Wenn du das Form in ein anderes Projekt einbindest - kannst du dann dort im Designer Controls hinzufügen? Das war bei mir damals problematisch.

27.12.2020 - 18:15 Uhr

System.Collections.ObjectModel.Collection<T> ist dafür vorgesehen.
Eigene Auflistungen zu basteln, und ist dafür ausgezeichnet geeignet.
Bestimmte Member sind protected virtual, sodass man mit Leichtigkeit gezielt das Verhalten modifizieren kann.
nämlich nur protected SetItem() und InsertItem() wären zu überschreiben - feddich.
So erbt man das komplette IList<T>-Interface, ohne auch nur einen Finger dafür zu rühren.

Wenn man auf Performance abzielt könnte man beim Einfügen sogar BinarySearch zum Auffinden der Einfüge-Position anwenden. Dazu einfach die innere Liste nehmen - das ist eine List<T>, und List<T> kann BinarySearch.
Dann muss beim Add nicht mehr sortiert werden. Nicht viel Aufwand, aber bei 10 Elementen scheint mir auch das unsinnig.

14.09.2020 - 21:57 Uhr

Du könntest eine Methode SetzenText(Textbox tb) schreiben.

static class SL
{
public static void SetztenText(Textbox tb)
        {
            tb.text="Hallo";
        }
}

Aufzurufen:

SL.SetztenText(this.texbox1);

Das würde von jedem Form aus gehen (ob sowas sinnvoll ist sei dahingestellt)

14.09.2020 - 21:34 Uhr

Ich habe jetzt die einzelnen Importphasen in eigene Funktionen gegliedert... Dassis schoma sehr gut, und der erste Schritt.
... Welche meiner Funktionen muss async sein und wo wird das await angewendet? Wurde schon gesagt: die Zeitfresser müssen Async.
Ich hab mal auf CodeProject ein Tut gebastelt, was zeigt, wie man mit minimalem Eingriff eine Methode in einen NebenThread schubst.
Die gezeigten Code-Snippets sind zwar vb, es hat aber auch eine c#-SampleSolution.
Wie gesagt: Es trifft sich sehr gut, dass du die Kandidaten bereits in eigene Methoden isoliert hast.
Async/Await
Was anfangs als zum schreien einfach anmutet erweist sich dann doch als typischer Rattenschwanz:*Ist eine Methode Async auf den Weg gebracht, musst du so lange verhindern, dass der Button nochmal geklickst wird (Suspend Gui) *Während das Teil läuft willst du eine Progressbar oder sowas (Update Gui) *Natürlich will der User den Vorgang auch canceln können (Cancellation) *Fehler müssen (fast immer) im Gui-Thread behandelt werden (Error-Handling)

Jo - wird alles behandelt in meim Tut.
(Wenn du es brauchbar findest, rate es up - ich wunder mich immer, was für Artikel auf CP irrwitzig hochgeratet sind, während so ein Fundamental-Artikel zu einem ich finde bahnbrechend neuem Feature bei weniger als 20 ratings rumdümpelt.)

14.09.2020 - 21:14 Uhr

ich hab grad was lustiges ausprobiert:
In den Settings eine bool-Property "ControlsEnabled" angelegt.
Einen Button aufs Form, und bei Databindings - ApplicationSettings ein Databinding eingerichtet zwischen dessen Property "Enabled" und my.settings.ControlsEnabled.
Weiters eine Checkbox aufs form, und deren Checked-Property auch an das Setting gebunden.
Jo, nun kannich mit der Checkbox den Button dis/en-ablen - und es ist ganz egal, auf welchem Form/UserControl der liegt.
Ist bei vielen Buttons vmtl. viel Geklickse, das einzurichten, aber ist ganz ohne Code zu schreiben.

12.11.2019 - 13:21 Uhr

HiTest weiss ich jetzt auch nicht, wie für das Problem anwenden.
Mit RectAngle.Intersect() kann man ermitteln, ob 2 Rechtecke sich überschneiden.
Also musst du deine TreeItems durchlaufen um festzustellen, wessen DarstellungsRechteck sich mit deinem Auswahlrechteck überschneidet.

09.03.2019 - 22:25 Uhr

Ich vermute, mit dem Binding stimmt was nicht.
Dann solltest du eine diesbezügliche Fehlermeldung ins Ausgabefenster bekommen, sobald das DataTemplate angewendet wird (also iwas damit anzeigt oder anzeigen soll).

09.03.2019 - 22:19 Uhr

Ich hab mal ein Tutorial verzapft, wo ich derlei Feinheiten der Xaml-Syntax bisserl auf Grund gehe.
Dazu hab ich einfach ein Stück Xaml (fast) ohne jede Syntax-Vereinfachuing formuliert, und anschließend die verschiedenen Vereinfachungen angewendet (Property-Attribute-Syntax, DefaultProperties, Markup-Extensions, TypConverter) - bis schließlich leidlich "normales" Xaml bei rauskommt.

24.11.2018 - 14:29 Uhr

Ähm - eigentlich - zumindest nach Ansicht einer recht grossen Community - sollte man Wpf so nicht programmieren.
Genuiner Bestandteil von Wpf ist der MVVM-Pattern, also statt des CodeBehinds sollte Databinding verwendet werden.
Wennde MVVM noch nie gehört hast, google mal danach.
Zusätzlich dazu gugge vlt. Wpf-AnwendungsStruktur
Ist zwar vb, aber strukturell gibts da kein Unterschied.

09.10.2018 - 03:15 Uhr

meine 5ct: Ich mag CodeFirst auch nicht besonders, weils da nicht mehr den Edmx-Designer gibt.
Der - als Entity-Relation-Diagramm - ist mir nämlich eine große Hilfe beim Konzipieren von Datenmodellen.
Bei CodeFirst habich Mühe, den Überblick zu behalten.
Ich gebe auch die Hoffnung nicht auf, dasses MS demnächst doch noch einfällt, auch EF.Core wieder mit ER-Diagramm-Designer-Unterstützung auszustatten.

09.10.2018 - 03:02 Uhr

Ach Abt - immer ein aufmunterndes Wort für die Anfänger! 😉

Und so unwidersprüchlich:

Wie sicherlich dem Wiki zu entnehmen ist, ist XSD einzig und allein zur Definition einer Struktur gedacht (ähm - welchem Wiki?)
Das XSD kann aber auch für andere Dinge verwendet werden, zB durch die strukturelle Vorgabe als IntelliSense Quelle in XML Editoren.

Und ich hätte noch ein, wofür man Xsd gebrauchen kann: Man kann sich damit eine Klassen-Struktur generieren lassen. Ich hab zwar grad vergessen wie das im Einzelnen geht, aber google "c#-Classes from xsd" müsste Anleitung erbringen.

Hat man diese Klassen-Struktur, so kann man eine Xml deserialisieren (Stichwort "Xml-Serialisierung"), und enhält c#-Objekte, die man mit c# manipulieren kann, und das Ergebnis kann man auch wieder serialisieren.
Auf diese Weise muss man mit Xml überhaupt nicht herumfuchteln, sondern es ist ein Instrument, um sehr komplexe Objektstrukturen zu persistieren oder zu transportieren.

02.10.2018 - 22:23 Uhr

hmm - zu "Fluent Code" erbrachte Google mir folgendes:
https://www.red-gate.com/simple-talk/dotnet/net-framework/fluent-code-in-c/
Ich sehe nicht, wie das dem TE helfen könnte.
Meinst du vlt. ein anderes "Fluent Code", und wenn ja welches?

02.10.2018 - 22:11 Uhr

Oh - das ist ein ziemlich gutes Control - da brauchste nur der DataSource eine BindingSource zuweisen, und wenn alles richtig konfiguriert ist, ist damit die ListView befüllt.
Gibt doch auch ein umfangreiches DemoProjekt zu dem Control - gibt das denn garnix her für deine Problematik?

02.10.2018 - 16:33 Uhr

ich wüsste nicht, dasses ein json-dictionary überhaupt gibt.
Ansonsten löscht man einen Eintrag aus einem Dictionary mit der Dictionary.Remove() - Methode.
Sehr hilfreich finde ich immer den ObjectBrowser, wo man etwa die dictionary-Klasse suchen kann, und alle verfügbaren Methoden und Properties sehen - inklusive ihrer Aufrufe-Konventionen.
Kennst du den ObjectBrowser? ist ein Built-In-Tool der IDE.

02.10.2018 - 10:42 Uhr

jo - habich gesehen, und wie das als Aufruf rauskommt auch verstanden.
Gefällt mir aber nicht, 3 TypParameter angeben zu müssen - da bleib ich lieber bei der Reflection/dynamic - Lösung.

Wie gesagt: Meine Kernfrage war eher prinzipieller Natur, ob in derlei gelagerten Fällen eine TypParameter-Einschränkung möglich ist, die nicht den TypParameter der Basisklasse mitliefern muss.
Dassis geklärt - ist nicht möglich.

02.10.2018 - 10:11 Uhr

Hätte das einen Vorteil gegenüber dem Ansatz, den ich bereits habe?
Das Feine an meim Ansatz ist ja, dass ich einen Datenabruf an den Service absetzen kann, meist mit einem Einzeiler.
Wie sähe der Datenabruf bei deim Ansatz aus?

01.10.2018 - 21:27 Uhr

Dassis etwas mühsam, weil es um Codes in VB geht, die auf Arbeit sind (und ich krankgeschrieben).
Aber ich habs jetzt mal vom Prinzip aussm Kopf glaub ziemlich korrekt hingebastelt.

Also auf ARbeit haben wir eine Anwendung, die ca. 50 InterfaceMember in 10 WcfServices konsumiert, und das ist eine wahre "DoRepeatYourself"-Orgie, schlimmer noch, die Selbstwiderholungen sind teilweise auch noch inkorrekt implementiert. (hysterisch gewachsener Code).

Also wenn man nur einen besch... String abrufen will muss man folgende Übung absolvieren:


      static string GetFoo() {
         // dazu Logging, Localisation, Errorhandling, response-Header-Auswertung - in immer derselben Implementierung
         using (var myClient = new ServiceClient())
         using (var scope = new OperationContextScope(myClient.InnerChannel)) {
            OperationContext.Current.OutgoingMessageProperties["Autentication"] = _AutenticationToken;
            return myClient.foo().Data;
         }
      }

Wie gesagt (im Comment angedeutet), das eigentliche Code-Gebrabbel ist hier weggelassen, realiter ists das 3-fache, und ist immer dasselbe.

Das Gebrabbel habich nun isoliert - der Pattern heisst glaub "Function höherer Ordnung einführen":


      static string GetFoo2() {
         return Execute((ServiceClient clnt) => clnt.foo().Data);
      }

      static TResult Execute<TService, TResult>(Func<TService, TResult> fnc) where TService : IDisposable, new() {
         // dazu Logging, Localisation, Errorhandling, response-Header-Auswertung - einmal implementiert, und richtig
         using (var myClient = new TService()) {
            IClientChannel chnl = GetChannelFromClient(myClient);
            using (var scope = new OperationContextScope(chnl)) {
               OperationContext.Current.OutgoingMessageProperties["Autentication"] = _AutenticationToken;
               return fnc(myClient);
            }
         }
      }

Wie du siehst - GetFoo2 macht jetzt nur noch, was man denkt was GetFoo2 im Kern zu machen hat - alles annere ist an einem Punkt konzentriert und sauber.
Bisserl unsauber halt noch das GetChannelFromClient(), weil das hampelt - wie du dir auch gedacht hast - mit Reflection rum, bzw. mit dynamic.

Jo, und da bin ich bisserl frustriert, dass ich die TypEinschränkung nicht so formulieren kann, dass ich normal auf myClient.InnerChannel zugreifen kann.
Weil eigentlich sind ja alle notwendigen TypInformationen gegeben.

Es ist also einerseits ein konkretes Problem, andererseits ein abstraktes: Es scheint mir ein Mangel der Sprache zu sein, weil prinzipiell wäre hier doch die Möglichkeit gegeben, auch Polymorphie bereitzustellen.
Nämlich die nicht-generischen Member eines generischen Typs könnte man doch eiglich zugreifbar machen, auch ohne dass der konkrete TypParameter bekannt ist.

Man kanns auch als DesignFehler der ServiceBase<T> - Klasse sehen: Täte die von einer nichtgenerischen ServiceBase erben, welche den .InnerChannel veröffentlichte, wäre ich ebenfalls nu der Notwendigkeit enthoben herumzureflecten.

30.09.2018 - 21:10 Uhr

Hi!

Ich bin derzeit mit Wcf-Webservices befasst, und immer wenn ich einen instanziere muss ich auch einen ObjectContext instanzieren, und myWebService.InnerChannel übergeben.
.InnerChannel ist nichtgenerische Property der Service-Basisklasse, also von ServiceBase(Of TInterface).

Ich würde nun gerne eine generalisierte Methode coden, die gleich beides erstellt: den WcfService und den ObjectContext, und die für alle möglichen WcfService verwendbar wäre - prinzipiell sowas:

public void InitService<TService>()
where TService : ServiceBase<?>, new {
   _Service = new TService();
   _Context = new ObjectContext(_Service.InnerChannel);
   //...
}

Aber leider weiss ich nicht, wie ich die ServiceBase<TInterface> als TypParameter-Einschränkung formuliere, weil ich TInterface nicht habe.
Tatsächlich brauche ich TInterface auch nicht, denn ich will ja auf den nichtgenerische Property .InnerChannel zugreifen - hat ja mit dem Interface nix zu tun.

Geht das überhaupt?

(Übrigens "ObjectContext" ist nicht der richtige Datentyp-Name des 2.Objektes, das ich erstellen muss - ist mir entfallen. Aber ich hoffe das prinzipielle Problem ist klargeworden?)

24.08.2018 - 15:57 Uhr

verwendetes Datenbanksystem: SqlServer

Ich hab eine komplizierte Abfrage, die läuft recht lange und löscht recht viel.
Der Db-Admin wünscht, dass die Löscherei in Chunks von 500 Datensätzen erfolgt.
Da habich eine komplizierte Lösung, wo ich erst nachzähle, wieviele denn gelöscht werden, dann die Anzahl der dafür benötigten Chunks, und dann in einer While-Schleife abfahren.

Etwas einfacher, aber iwie auch skurril ist eine Lösung, wo ich das Output-Feature dazu nutze, herauszubekommen, wieviele Datensätze gelöscht wurden, und wenn weniger als ChunkSize, die Schleife verlassen - beispielCode (b.Bed auskopieren + testen):


--Chunken mit dem Output-Feature
create table #todelete(numb int )
create table #todelete2(numb int )
declare @count int=0
while @count<100
	Begin
		insert into #todelete values(@count)
		insert into #todelete2 values(@count*2)
		select @count=@count+1
	end

declare @ChunkSize1 int = 15
create table #deleteds(numb int )
declare  @delCount int = @ChunkSize1
while @delCount = @ChunkSize1
	Begin
		Begin TRANSACTION;
			Delete Top (@ChunkSize1) td
			output 1 as numb into #deleteds
			FROM #todelete td
			join #todelete2 td2 on td.numb=td2.numb
		COMMIT TRANSACTION;
		select  @delCount= count(*) from #deleteds;
		select  @delCount
		truncate table #deleteds;
	End

select   count(*) Rest from #todelete;
drop table #deleteds
drop table #todelete
drop table #todelete2

(das mit toDelete, toDelete2 soll andeuten, dass die Abfrage komplex ist)
Meine Frage: Gibts da nicht was einfacheres?

20.05.2018 - 20:44 Uhr

Übrigens enthält Wpf auch eine fabelhafte Vector-Struct:
System.Windows.Vector

27.12.2017 - 13:41 Uhr

ich bevorzuge und benutze immer Docking - evtl. kombiniert mit einem TableLayoutpanel.
Damit krieg ich bislang jedes Layout ohne eigenen Sizing-Code hin, und funzt auch immer.

Zum die möglichkeiten angugge video:
Layout in WinForms

11.11.2017 - 19:01 Uhr

braucht man dank async/await kein Invoke mehr jepp.

Ansonsten denke ich, ein grundlegender Fehler hier ist, dass versucht wird, die Arbeits-Methode iwie async zu modifizieren.
Das ist nicht erforderlich (kann sein, dasses möglich ist, aber erforderlich ists nicht, und obs und wanns sinnvoll ist weiss ich auch nicht, weil ich mach das nie so.)

Imo soll die Arbeits-Methode arbeiten, und sich nicht um die Nebenläufigkeit kümmern.
Nebenläufigkeit erreicht man durch einen bischen komischen Aufruf, mit Await, Task.Run() und den eiglichen Aufruf in eine anonyme Methode gewrappert.

Hier Tut dazu:
Async/Await: Unblock Gui without any additional Line of Code

11.11.2017 - 17:43 Uhr

jo - probierma.
ich gebe noch zu bedenken, dasses oft scheitert, eine "EierlegendeWollmilchsau" zu konstruieren.
Jdfs. bei mir gerät die Verwaltung von auch nur mässig komplexen Optionen meist zu einer eigenen Baustelle, oft auch nicht klein, und sehr anwendungs-spezifisch.
Da muss dann ein eigenes Datenmodell her und ein eigenes Gui - da beißt die Maus kein Faden ab.
Aber probierma: Ich sag ja nicht, dass die "EierlegendeWollmilchsau" prinzipiell immer unmöglich ist - manchmal gelingts auch.
Aber meist eben nicht, daher meine Warnung, da allzuviel Zeit reinzustecken.

13.08.2017 - 08:56 Uhr

Du kannst im FormDesigner das DialogResult von Buttons festlegen, damit bewirkst du gleichzeitig, dass diese Buttons das Form schließen - ohne weiteren Code schreiben zu müssen.
gugge Filmle: Dialoge implementieren
Indem du so den Designer seinen Job machen lässt, entfällt der Button-Klick-Code, und wird insgesamt merklich einfacher:

//nur nötige usings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApp1 {
   public partial class Form2 : Form {
      public uint Kal {
         get { // ifs ohne {} einzeilig notieren
            if (Xy_l.Checked) return 1;
            if (Xl_ylog.Checked) return 2;
            if (Xlog_yl.Checked) return 3;
            return 4;
         }
      }
      // readonly props, die ihren Wert selbst ermitteln (kein BackingField)
      public decimal X_min { get {return Convert.ToDecimal(Xmin_box.Text); } }
      public decimal X_max { get { return Convert.ToDecimal(Xmax_box.Text); } }

      public Form2() {
         InitializeComponent();
      }
   }
}

Wobei das problematisch ist, decimal-Werte aus Textboxen zu lesen - das stürzt ab, wenn da jemand "Hallo Welt" reinschreibt.
Für Zahlen-Eingaben NumericUpdown nehmen.

09.08.2017 - 14:05 Uhr

also eine extra-Klasse, > 30 Zeilen Code, mit DependancyProperty - nur für ein popeliges Window-Closing-Event?
wie gesagt: fragwürdig.

09.08.2017 - 13:25 Uhr

Überhaupt, ich finde auch das propangierte Konzept mit dem "Interaction.Trigger" etwas fragwürdig. Ist das wirklich das Konzept, das man heute für solch zentrale Aufgaben verwendet? Jo, viele tun das, und finden das toll.
Manche aber auch nicht.
Ich zB. finde das so dermassen umständlich, dass ich mir lieber ein Control ins Viewmodel hole (ganz böse!! :evil: ), damit ich dessen Events behandeln kann.
Denn darum gehts ja bei der Interaction.Event-Trigger-Binding-auf-Commands: dass Events eines Controls behandelt werden.
Also den Vorteil, dass ich die Events so behandeln kann, wie ich sie brauche, erkaufe ich mir durch 2 nachteile:*geht nicht, wenn mehrere Controls ans selbe Viewmodel binden *soll wohl Probleme beim UnitTesting aufwerfen (ich habs noch nicht ersnsthaft probiert)

vlt. gibts noch mehr Nachteile - grad nicht im Kopf.
Ich wollte nur kundtun, dassichdas mit dem "fragwürdig" gut verstehe (oder gut zu verstehen glaube)

02.08.2017 - 21:43 Uhr

... was hier (in diesem Forum) darunter zu verstehen ist, ist in
>
recht prominent gleich am Anfang (Punkt 1.1) aufgeführt....

hmm hmm - dazu 2 Anmerkungen:1.Ich denke nicht, dass der von dir zitierte Artikel beabsichtigt, zu definieren, "was hier in diesem Forum unter 'Dokumentation' zu verstehen ist". 1.Wenn man sich dem tatsächlich unterwürfe, dann entginge einem so einiges, was imo unbedingt auch als Dokumentation zu werten ist - dort aber mit keiner Silbe Erwähnung findet.

02.08.2017 - 14:59 Uhr

Darum soll man ja auch ab und an in die Dokumentation schauen 😉 Das ist oft ein Problem, weil "die Dokumentation" gibt es garnet - jeder versteht was anderes darunter, und vielen sind die einfachsten Recherche-Möglichkeiten einfach unbekannt.
Ich etwa gucke ständig in den ObjectBrowser, und da sieht man sofort, dass das WpfTabControl die ItemsSource-Property von ItemsControl geerbt hat, von welcher auch die genannten Klassen Selector, Listbox und Combobox erben.

Hier Video zum OB, um den mal gesehen zu haben
Hier Versuch, die verfügbaren Dokumentationen mal zusammenzustellen

02.08.2017 - 07:27 Uhr

Wenn mans geschickt anstellt, kann man die meisten Bindings einfach im Xaml-Designer im PropertyGrid auswählen.
Und dabei sieht man auch eine Datenvorschau, und dann weiß man zu 90% bereits zur Designzeit, obs hinhaut oder nicht.

Hierzu habe ich inne App.Xaml eine MainViewModel-Resource angelegt, an die dann (siehe Bildle unten) d:DataContext binden kann:

<Application x:Class="MVVMTestProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml"
             		xmlns:vm="clr-namespace:MVVMTestProject.ViewModel" 
             >
    <Application.Resources>
    <vm:MainViewModel x:Key="MainViewModel"/>
  </Application.Resources>
</Application>

Wie's ichs hier gemacht hab ist noch sehr unsauber, es gibt verschiedene Ansätze, es sauber hinzukriegen, dass1.das MainViewModel nur einmal instanziert wird 1.dass es zur Designzeit nur Mockdaten bereitstellt, während Laufzeit-Funktionalität abgeklemmt bleibt
(Das ist in diesem Fall sogar nicht zwingend, weil das Repository selbst derzeit ein Mock ist, schnell genug, um auch im Xaml-Designer ladbar zu sein.)

Ich hab auch ausführliche Artikel und sogar Video gebastelt zum Thema:
BindingPicking-Video
mein MVVM-Artikel
Mein Artikel wird wohl auf geteilte Meinungen treffen, weil ich "unvollständiges MVVM" empfehle, wenn dessen vollständige Ausbildung für ein kleines Problem nur ein grotesker Wasserkopf wäre.
Aber die dortigen Sample-Zips zeigen immerhin, wie man eine Anwendung aufbauen kann, ohne die BindingPicking-Funktionalität des Xaml-Editors zu torpedieren.

31.07.2017 - 19:43 Uhr

für genau solche Gui-logischen Zusammenhänge ist das Viewmodel da.

Ich (und nicht nur ich, sondern wohl alle hier, die sich bisserl mit Wpf auskennen) empfehle(n) dir also sehr, dich über den MVVM-Pattern schlau zu machen, und deine Anwendung diesem Pattern entsprechend zu strukturieren.

In Folge wirst du mit DataGrid-Events garnix mehr zu tun haben, sondern da ist nur triviale Logik in der Viewmodel-Klasse zu hinterlegen und feddich.

30.07.2017 - 12:28 Uhr

wie gesagt: Es gibt mehrere Wege - einer wäre mit Label.Autosize.True und AnchorStyle.None auf einer TableLayoutPanel-Zelle.
Das zentriert auch ohne TextAlign.Center.

Also auch wenn man sich mitm WinForms-Layoutsystem auskennt, lohnt sichs glaub trotzdem, die vids anzugugge - der eine oder annere Kniff mag immer noch dabei sein, den man nicht kannte.
Und wer auch nur eins der Dinge nicht kennt: SplitContainer, DokumentenStruktur-Ansicht, TabControls, TableLayoutPanel, FlowLayoutPanel - naja, der sowieso.

30.07.2017 - 09:18 Uhr

Es gibt mehrere Wege, das zu lösen. "immer Mittig unter was anderes" löse ich zB vorzugsweise mit TableLayoutPanel.

Zum WinForms-Layout-System habich Videos gemacht, weil bei nur Erklären ohne zugucken kriegt man den Dreh wohl nur mühsam raus. Also Videos: LayoutSystem WinForms

25.07.2017 - 15:04 Uhr

Wie gesagt, dass und wie die FWs miteinander kompatibel sind ist nicht die Frage.
Mein Bauchgefühl sagte mir halt, wenn ich eine Assembly in FW4.0 code, dann lädt sie auch zB die WinForms.dll-4.0, und wenn im selben Programm eine annere Assembly mit FW4.5 kompiliert, so lädt letztere die WinForms.dll-4.5, und somit wären 2 Winformse geladen.

Aber nu seh ich, dass sowohl inne FW4- als auch inne FW4.5 - Assembly die eingebundene WinFormsdll die Versionsnummer 4.0 hat.

Also wird bei verschiedenen FWs nur verschiedene msCorlibs geladen, die System.Windows.Forms, System.Data etc. aber für beide dieselbe benützt?

25.07.2017 - 13:24 Uhr

Wir produzieren Anwendungen, die Assemblies zusammenbinden, von denen manche mit FW4.0 kompilieren, andere mit FW4.5.
Die 4.5er - Anwendungen haben Verweise auf die 4.0er Assemblies, also das Konstrukt funktioniert, nur vermute ich einen überhöhten Speicher-Bedarf - wobei mir ein Kollege widerspricht.

Weiß jmd ein schlagendes Argument, oder eine INet-Resource, die das klärt?

thx

18.07.2017 - 11:18 Uhr

Aber disposed das auch die entfernten Controls?
Weil sonst hätte man ja leicht ein schönes Memory-Leak.

05.06.2017 - 03:15 Uhr

Hmm - also ich finde Jens91' Lösung alles annere als trivial. Klar - elegante Lösungen sehen am Ende immer fast trivial aus - aber lass ma gucken:
Er geht sehr geschickt mit DataTable um, und er hat sich ganz spezifische Eigenarten des Chart-Controls selbst erarbeitet:
.DataSource, .Datebind() und die Series-Collection mit ihren verschiedenen ValueMember-Eigenschaften - da muss man erstmal drauf kommen, was das alles zu bedeuten hat, und wie's ineinander greift und zusammenspielt! 👍
/OT

@Jens91
Eigentümlich und fragwürdig finde ich, dass es funktioniert.
Imo müsste deine DataTable nach dieser Konfiguration nur Columns mit DataType.String aufweisen, und deshalb ist mir verwunderlich, dass das ChartControl das akzeptiert, denn die XYValues sollen doch wohl numerisch sein, oder?

Imo hättest du die DataColumns auf DataType.Double konfigurieren müssen, und beim Einlesen die csv-Strings mit Double.Parse() in eben diesen Datentyp konvertieren.


Ach - ich hab übrigens mal ein klein Tut gemacht zum Chart-Control, und was man da alles im Designer dran drehen kann, und wo die Doku dazu ühaupt zu finden ist:
ChartSample
Ist auch bisserl Code dabei, und der ist (leider?) auf VB, aber die Designer-Geschichten sind in c# ja dieselben, und einiges andere dürfte für dich auch interessant sein, wenn du dich mittm ChartControl auseinandersetzst.

05.06.2017 - 02:31 Uhr

mag sein, dass du recht damit hast, erstmal Grundlagen aufholen zu wollen, ehe du dich in wpf hineinstürzt.
Mag aber auch nicht sein.
Zumindest in meim Falle liegst du hiermit falsch:

beim lesen der Doku ein Haufen Information die als vollkommen selbstverständlich betrachtet wird. Meine Wenigkeit betrachten keinerlei Information als selbstverständlich.
Es mag so erscheinen, wenn und weil ich Fachbegriffe ganz unverfroren verwende, so als würde ich sie vorraussetzen.
Tatsächlich setze ich sie nicht voraus, sondern will provozieren, dass nachgefragt wird.
Oder andersrum: Ich bin gradezu auf Nachfragen angewiesen, denn ich weiß ja nicht deine Wissenslücken (meine eigenen weiß ich übrigens auch nur zum Teil).
Und darum bleibt mir nix anneres als so zu tun als wären da keine, und darauf zu bauen, dass du dich traust, nachzufragen.
Ich vermute, dir ist das Konzept Namespace nicht richtig verständlich. Aber solange du das nicht sagst, kann nicht drauf eingegangen werden.


Oder mal ganz anderer Vorschlag: Beantworte doch einfach meine Frage(n)!

  1. Wie heisst deine Klasse, von der du erben willst, und 2) wie sieht dein Xaml aus, bevor es von deiner Klasse erbt? Oder setzt das auch schon zuviel voraus?
    Ich hab dir ja sogar die Motivation dieser Frage gegeben - ist wirklich schade, dass du sie trotzdem ignorierst.
    (schade für uns beide: Ich fühle mich übergangen, du vergibst die Chance, was zu lernen)
04.06.2017 - 21:20 Uhr

Wie heisst deine Klasse, von der du erben willst, und wie sieht dein Xaml aus, bevor es von deiner Klasse erbt?
Mit diesen Informationen kann man deine Frage vlt. konkret beantworten.

03.06.2017 - 22:44 Uhr

man kann auch im Xaml von Klassen erben.
Die allererste Zeile benennt als erstes die Basis-Klasse.
Danach richtet sich auch das Codebehind.

Ob das eine gute Idee ist, wage ich aber stark zu bezweifeln

08.05.2017 - 06:07 Uhr

Hi!

In unsere Firma wird ein selbstgebasteltes Lokalisierungs-System verwendet, was die Programm-Wartung imo exorbitant behindert.
Aber bevor ich die Kollegen mit den Vorzügen der Standard-Vorgehensweise konfrontiere, hätte ich gerne Erfahrungsberichte aus anner Leuts Praxis, weil meine Erfahrungen gehen über ein paar Tests nicht hinaus.

Mit "Standard-Vorgehensweise" meine ich, dass man beim Form Localizable.True einstellt, dann zB Language.fr-fr, und dann das Gui französisch betextet.
Dann werden ja entsprechende Resorucen generiert und Satteliten-Dlls.

Ich persönlich habe ja einen sehr angenehmen Eindruck von dieser Vorgehensweise - ja wie gesagt: bestätigt sich das auch in eurer Praxis?

Ist das durchgängig anwendbar, oder sind in bestimmten Fällen Nacharbeiten erforderlich?
Etwa Messagebox-Texte anzeigen findet ja nicht im Designer statt - wie gaht man damit um?
Oder Spaltenbeschriftungen von Datagridviews? Oder gar von zugekauften TabellenControls - wird das auch durch die Standard-Vorgehensweise unterstützt?

06.05.2017 - 07:29 Uhr

ich denke, der Code wird nicht durchlaufen, oder er berbeitet ein anderes StackPanel als was du denkst - also das wären Erklärungsmöglichkeiten.

05.05.2017 - 16:16 Uhr

Fehlermeldung:
Fehler BC31541 Ein Verweis auf die MailItemClass-Klasse ist nicht zulässig, wenn in der Assembly die Einbettung von Interoptypen konfiguriert ist. OutlookAddIn2016

ich fange ein Outlook-PlugIn an, und finde im ObjectBrowser reichhaltige Information zur MailItemClass, aber offsichtlich soll ich die nicht benutzen , sondern das Interface MailItem, was zwar funktioniert, zu dem der Objectbrowser gar keine Infos bereitstellt.
Darüberhinaus finde ich im OB noch das Interface _MailItem, mit allen Informationen ausser den Events.
Mit wohl allen anderen Klassen der Outlook-Lib gehts genauso.

Meine Frage ist, was es mit dieser eigenartigen Verdreifachung auf sich hat?
Also ich kann glaub damit umgehen, aber ich versteh den Sinn nicht, und es erscheint mir auch unpraktisch - zB weil auch Intellisense nicht funktioniert etc.

03.05.2017 - 16:59 Uhr

Vielen Dank - nu gehts, und nu kann ich auch was einfaches basteln, wasses auch tut:
Das mit der attached-bool-Property, wo man damm in einem ListboxItem-Style eine Farbe triggern kann, das gefällt mir sehr gut, und das habe ich stark verallgemeinert, nämlich ich hab eine AttachedProp, mit der man nu jedem FrameworkElement IsHovered zuordnen kann, und Trigger können dann das Element hervorheben - ob nu durch BackColor, ForeColor, Fonts etc. ist ja egal.
Den Rest habich wie gesagt im Codebehind belassen, und ist auch nicht viel:


   public partial class MainWindow : Window {
      public MainWindow() { InitializeComponent(); }

      private void ListBox_MouseLeave(object sender, MouseEventArgs e) { SetHoveredUpto((ListBox)sender, null); }

      private void ListBox_MouseMove(object sender, MouseEventArgs e) {
         var listBox = (ListBox)sender;
         var itm = (FrameworkElement)e.OriginalSource;
         var target = listBox.ItemContainerGenerator.ContainerFromItem(itm.DataContext);
         SetHoveredUpto(listBox, target);
      }
      private static void SetHoveredUpto(ListBox listBox, DependencyObject target) {
         var genr = listBox.ItemContainerGenerator;
         var hover = false;
         for (var i = listBox.Items.Count; i-- > 0; ) {
            var itm = genr.ContainerFromIndex(i);
            if (itm == target) hover = true;
            itm.SetValue(FweAttaches.IsHoveredProperty, hover); // setzen der attachten Prop
         }
      }
   }

Die IsHovered-Attached-Prop:


   public static class FweAttaches { // (evtl fällt mir auch noch mehr ein, was an FWEs zu attachen sinnvoll ist)
      public static readonly DependencyProperty IsHoveredProperty = DependencyProperty.RegisterAttached("IsHovered", typeof(bool), typeof(FweAttaches), new PropertyMetadata(false));
      public static bool GetIsHovered(FrameworkElement d) { return (bool)d.GetValue(IsHoveredProperty); }
      public static void SetIsHovered(FrameworkElement d, bool value) { d.SetValue(IsHoveredProperty, value); }
   }

Meine Xaml-Listbox sieht komplizierter aus als die von Sir Rufo, dafür entfällt der externe Style:


    <ListBox Grid.Row="2"  Grid.Column="3" ItemsSource="{Binding Persons}"  DisplayMemberPath="Name" Padding="4" MouseLeave="ListBox_MouseLeave" MouseMove="ListBox_MouseMove">
      <ItemsControl.ItemContainerStyle>
        <Style  TargetType="ListBoxItem">
          <Style.Triggers>
            <Trigger Property="local:FweAttaches.IsHovered" Value="true">
              <Setter Property="Background" Value="{x:Static SystemColors.InactiveSelectionHighlightBrush}"/>
            </Trigger>
          </Style.Triggers>
        </Style>
      </ItemsControl.ItemContainerStyle>
    </ListBox>

Wie gesagt: Solange man dieses Verhalten nur in einer Listbox braucht, ists deutlich einfacher, auf das Behavior-Brimborium zu verzichten - sei es nun im Blend-Style oder im AttachProp-Style umgesetzt.
Auslagern, wenns erforderlich wird, kann man ja immer noch (eben wenns erforderlich wird).
Und was daran mehrfach verwendbar ist - habe ich sogar schon ausgelagert: Diese fabelhafte IsHovered-Prop, die werd ich zukünftig noch öfter bemühen, wenn ich mit ListViews, Listboxen, Treeviews zu tun kriege.