Laden...

Forenbeiträge von marcial187 Ingesamt 56 Beiträge

15.07.2016 - 17:14 Uhr

Genau die Antwort habe ich gebraucht.

Ich muss sowohl Knoten als auch Kanten im Bereich ≤ 10k darstellen. Die Performance der Darstellung von Linien in 3D über Polygone ist genau meine Befürchtung. Im verlinkten Beispiel (High Performance WPF...) sah es zwar ganz ok aus, bevor ich mich da aber reinstürze wollte ich erst andere Möglichkeiten in Betracht ziehen.

2D habe ich für meinen Anwendungsbereich (sowohl WinForms als auch WPF) schon durch, insbesondere die Tutorials hier im Forum. Ich werde mich dann dran setzen und das ganze zunächst mal in WPF als 2D rendern.

Gibt's auch ganz nette Videos, wo es im Prinzip doch recht akzeptabel aussieht:
https://www.youtube.com/watch?v=SOOsJjgHgi8

Wenn das Ergebnis gut genug ist, dann reicht mir das auch. 😃

Also vielen Dank für deine Hilfe!

Ich melde mich dann nochmal, wie es gelaufen ist 😉

Edit: Hab mir analog aus der Bib auch mal schnell "Windows Presentation Foundation : das umfassende Handbuch" für die 2D und 3D Kapitel und " 3D-Programmierung für Windows" geholt 😉

15.07.2016 - 08:45 Uhr

Vielen Dank für deine Antwort!

Die bin ich natürlich schon alle durchgegangen 😉

Bisher orientiere ich mich insb. an diesem Projekt:
High performance WPF 3D Chart

Damit kann ich das ganze auch bereits recht gut abbilden.

Meine Frage ist eher der Natur, ob es speziell für die Darstellung von Knoten-Kanten Diagrammen Ansätze gibt, die sich besonders gut eignen. Vllt hat jemand ja auch schon mal ein ähnliches Projekt angegangen und kann die aus seiner Sicht beste Herangehensweise erläutern. 😃

15.07.2016 - 08:29 Uhr

Danke für deine Antwort!

Das Projekt dreht sich so wie ich das sehe um 2D oder?
Habe es - wenn ich mich richtig erinnere - auch zu der Zeit, als ich mich mit 2D beschäftigt habe durchgearbeitet.

15.07.2016 - 07:54 Uhr

Hallo zusammen,

nach 2D beschäftige ich mich nun ein bisschen mit 3D 😉

Und zwar suche ich eine möglichst simple Variante zur simplen Darstellungen von Linien/Pipes und Punkten (bzw. Quader, Knoten).
Ganz grob in etwa wie im Anhang (ohne das gräuliche Modell im Hintergrund)
(Quelle: https://www.vr.rwth-aachen.de/person/16/)

Die Anforderungen sind wirklich gering, weswegen ich gerne auf alles was im Standard VS2015 Umfeld liegt zurück greifen würde.

Konkret möchte ich Folgendes umsetzen:

  • Darstellung eines Graphs aus Knoten und Kanten in 3D, Anzahl Knoten & Kanten: mehrere 1000
  • Navigieren durch das Modell: Panning, Zooming, Rotation
  • Flattening bzw. Projektion von 3D auf 2D

Die Koordinaten für den Graph bekomme ich als XML.

Das ist im Prinzip alles, ich brauche keinerlei Effekte, keine weitere Interaktion usw.

Wenn es eine einfache Lösung gibt, würde ich es wie gesagt bevorzugen, mich auf "Standard VS2015" Bibliotheken zu beschränken, d.h. am besten ohne iwelchen externen DLLs, Projekte usw.

Was würdet ihr mir unter diesen Aspekten empfehlen?

Viele Grüße & Danke im Voraus!

02.07.2016 - 19:50 Uhr

Habe jetzt doch noch eine Lösung erhalten, die ich nicht vorenthalten möchte:

Man muss ganz einfach auch die DataRow Klasse um INotifyPropertyChanged erweitern (wie ihr schon angemerkt habt, feuert das ganze nicht bei Änderungen).

Also in etwa so:

<DataTrigger Binding="{Binding Path=DataContext.Row.RowState,
             RelativeSource={RelativeSource Self}}" 
             Value="Unchanged">
    <Setter Property="Foreground" Value="Red" />
</DataTrigger>
public class DataTableExt: DataTable
{
    protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
    {
        return new DataRowExt(builder);
    }

    protected override void OnRowChanged(DataRowChangeEventArgs e)
    {
        base.OnRowChanged(e);
        // row has changed, notifying about changes
        var r = e.Row as DataRowExt;
        if (r!= null)
            r.OnRowStateChanged();
    }
}

public class DataRowExt: DataRow, INotifyPropertyChanged
{
    protected internal DataRowExt(DataRowBuilder builder) : base(builder)
    {
    }

    internal void OnRowStateChanged()
    {
        OnPropertyChanged("RowState");
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Bringt dann die gewünschten Ergebnisse.

Nun eine andere Frage (vll wäre ein extra Thread sinnvoller?):

Folgendes Szenario:
Ich möchte gewisse Inhalte relativ umfangreiche XML Dateien vergleichen und Unterschiede visualisieren. Die Dateien beinhalten viele Attributen unterschiedlicher Elemente und einige Verschachtelungen. In WinForms habe ich das ganze dann in der Tat auf verschiedene DataTables runtergestrippt. Das heißt für jeden Node-Typ eine DataTable, für jedes Attribut eine Spalte.
Visualisiert wird das ganze in WinForms im DataGridView dynamisch je nachdem was zur Laufzeit ausgewählt wird.

Jetzt wollte ich das ganze mal versuchen in WPF gemäß MVVM abzubilden. Das heißt für jeden XML Node Typ eine Klasse, jedes Attribut eine Klasseneigenschaft. On Top sind diese Eigenschaften eine eigene Klasse, um den alten und neuen Wert und den Status "Alt, Neu, Geändert" abzugreifen (vgl. DataRow, DataCell).

Hab mir dazu ein Tool geschrieben, die ganzen Klassen und den Code fürs einlesen zu schreiben, das war ja noch ok.

Hier mal ein vereinfachtes Beispiel:


	public class XMLElement1
	{
		public ObjectValue SomeValue1 {get; set; }
		public ObjectValue SomeValue2 {get; set; }
		// ...
		// beliebig ObjectValues 1-N
		public ObjectValue SomeValueN {get; set; }
	}
	
	// ... 
	// beliebig viele XMLElemente 1-M
	
	public class ObjectValue
    {
        public enum ObjectState
        {
            Unchanged,
            Added,
            Modified,
            Deleted,
        }

        public string newValue { get; set; }
        public string oldValue { get; }
        public ObjectState state { get; set; }

        public ObjectValue(string val, ObjectState state = ObjectState.Unchanged)
        {
            this.newValue = val;
            this.oldValue = val;
            this.state = state;
        }
	}

Jede Art von Liste eines XMLElementX bildet die Befüllung des DataGrids.

Kritisch wird es jetzt beim Anlegen der DataGrids. Wäre die Vorgehensweise, tatsächlich für jede Klasse eine GridDefinition in XAML hardcoded zu schreiben?
Denn: Ich muss zum einen auf die in jeder Klasse unterschiedlichen Eigenschaften zeigen. On Top muss ich noch auf die Eigenschaft "alter Wert, neuer Wert" etc. verweisen.

Das ist ein extremer Schreibaufwand in XAML.

Habe auch schon Workarounds erfolgreich getestet bei denen ich bspw. einfach die AutoGenerateColumns Methode abgreife und dann die jeweiligen Bindings im Code automatisiere.

Nur würde ich gerne nach "best practice" vorgehen. Was meint ihr in diesem Fall?

27.06.2016 - 06:27 Uhr

Bei DataRowView bin ich mir nicht sicher, evtl. lösen die das Event. DataRow / DataRowState macht es aufjeden Fall nicht.

Wenn ich das Grid danach aber "aktualisiere" (z.B. als User per Sortieren), kommen die Änderungen. Ein kleiner Hack wäre dann einfach die Zeile neu zu zeichnen, wenn sich ein Wert ändert. Daran sitze ich jetzt - auch das ist nicht so simpel wie ich dachte.

An sich ist die ganze Sache aber etwas ernüchternt. Ich kann in einem 3 Zeiler ein Event vom DataGrid nehmen und die farbliche Änderung einfach im Code schreiben - würde es aber gerne, wie vorgesehen, in XAML machen. Damit widerspricht es dann MVVM ist aber um Welten simpler, als auf DataTables zu verzichten und anzufangen, für jede Tabelle, die ich anziehe (und das sind etliche), separate Klassen zu hardcoden.

26.06.2016 - 20:22 Uhr

Hab die Lösung erhalten:

<DataTrigger Binding="{Binding Path=DataContext.Row.RowState,
             RelativeSource={RelativeSource Self}}" 
             Value="Unchanged">
    <Setter Property="Foreground" Value="Red" />
</DataTrigger>

So einfach kann es sein. Fehler: Value=Unchanged ohne "DataRowState.".

Im Nachhinein logisch, aber wenn man es nicht weiß kommt man nur durch rumprobieren drauf. Das ist, was ich an XAML vermisse. Im Debugger zur Laufzeit via Code kann ich die Möglichkeiten und Resultate direkt sehen und muss nicht rumraten. Hier bin ich quasi aufgeschmissen, wenn ich nicht weiter weiß.

Edit:

Bin doch noch nicht am Ziel. Änderungen werden nicht direkt visuell dargestellt, sondern erst wenn sich das Grid neu zeichnet (bspw. beim Sortieren).

26.06.2016 - 17:30 Uhr

Sooo bin solangsam am Verzweifeln... habe etliche der Ansätze probiert, die es im Internet so gibt.

Ich komm nicht dahinter, wie ich die Property RowState richtig binde. Auch Events wie CellEditEnding schaff ich nicht im XAML zu triggern.

Bsp. Property:


        <Style x:Key="RowStateStyle2" TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=DataContext.Row.RowState, RelativeSource={RelativeSource Self}}" Value="DataRowState.Modified">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
            </Style.Triggers>
        </Style>

Hier bin ich bei Binding Path jede Möglichkeit durchgegangen, die mir eingefallen ist.
Was mir am meisten Kopfschmerzen bereitet ist, dass ich keine Chance habe in irgend einer Form zu "debuggen".

In WinForms generiere ich meine Controls größtenteils zur Laufzeit. Dadurch bin ich sehr flexibel was das Auswerten davon angeht und komme immer relativ schnell zum Ziel.

Hier funktioniert es einfach nicht und ich kriege keinerlei Feedback. Intellisense ist innerhalb der Markups in XAML auch nicht gegeben.

Hat irgendjemand eine Idee woran es gerade scheitert?

26.06.2016 - 13:08 Uhr

Servus FZelle,

danke für deinen Beitrag.

Ich glaube im Laufe des Tages hatte ich diesen Ansatz auch schon mal implementiert, allerdings mit einem anderen Setter Value.

Habe es jetzt so wie von dir vorgeschlagen implementiert, das Ergebnis ist leider das gleiche:

  • Geänderte Zeilen/Zellen werden farblich nicht geändert.
  • Die ausgewählte Zelle wird weiß überdeckt (Text ist nicht mehr sichtbar).

Auch der Debugger macht keinen Stop, wenn ich einen Haltepunkt setze:


        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var val = (DataRowState)value; // kein Stop bei Haltepunkt

Verknüpft er eventuell den Pfad nicht richtig?

26.06.2016 - 11:30 Uhr

Hallo zusammen,

sitze seit dem Wochenende an WPF und versuche ein bisschen, meine WinForms Programme dort umzusetzen.

Folgendes Problem:

Ich habe mehrere DataGrids, die alle an DataTables gebunden sind. Die DataTables werden dynamisch zur Laufzeit über SQL befüllt. Änderungen sollen dem Nutzer farblich hervorgehoben werden (neu=grün, geändert=gelb, gelöscht=rot).

In WinForms habe ich das mit DataGridViews mittels _RowPostPaint und der RowState der gebundenen DataTableRow realisiert (Code ist sehr vereinfacht dargestellt):

private void DataGridViewTest_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    DataRow row = (this.Rows[e.RowIndex].DataBoundItem as DataRowView).Row;
    switch (row.RowState)
    {
        case DataRowState.Added:
            myBitmap = new Bitmap(imageList.Images[1]);
            this[0, e.RowIndex].Style.BackColor = CellChangesColorAdded;
            break;
        case DataRowState.Modified:
            string sValOld = row[0, DataRowVersion.Original].ToString();
            string sValNew = row[0].ToString();
            if (sValOld != sValNew)
            {
                this[0, e.RowIndex].Style.BackColor = CellChangesColorMod;
            }
            break;
        case DataRowState.Deleted:
            this[0, e.RowIndex].Style.BackColor = CellChangesColorDel;
            break;
    }
}

Ich bin etliche Ansätze in WPF durchgegangen (z.B. hier), komme aber nicht zum gewünschten Ergebnis. Ich möchte nicht die ganzen Spalten in irgend einer Form hardcoded in XAML schreiben.

Ich denke eine gute Lösung wäre irgend eine HelperClass, die entsprechend dem aktuellen DataRowState den passenden Style zurück gibt. Diesen Ansatz konnte ich noch nicht umsetzen, da ich nicht weiß, wie ich in XAML festlege, dass sich der Zeil auf die DataGridRow bzw. Cell beziehen soll und das ganze mit einem Changed Event der DataTable verknüpfe.

Momentan mache ich folgendes:
XAML:


    <Window.Resources>
        <Style x:Key="MyStyle" TargetType="{x:Type DataGridCell}">
            <Setter Property="Background" Value="Green" />
        </Style>
    </Window.Resources>
...
        <DataGrid x:Name="dataGrid" Grid.Row="4" Grid.ColumnSpan="6"
                  ItemsSource="{Binding}"
                  >
        </DataGrid>

und greif das CellEditEvent ab:
.cs:


dataGrid.DataContext = dataTable.DefaultView; // Table filled by SQL query
dataGrid.CellEditEnding += dataGrid_CellEditEnding;

// Problem: Änderungen bleiben nicht bestehen, wenn nutzer bspw. neu sortiert
    private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (e.EditAction == DataGridEditAction.Commit)
        {
            TextBox tb = e.EditingElement as TextBox;
            DataGridCell cell = tb.Parent as DataGridCell;
            // ... evaluate row changes and change color accordingly
            //cell.Background = new SolidColorBrush(Colors.Yellow); // set style instead of color
            cell.Style = (Style)this.Resources["MyStyle"]; // color is changed to green, according to defined style
        }
    }

Problem: Die Änderung bleibt nicht bestehen, wenn der Anwender bspw. neu sortiert und es ist sicher keine schöne Lösung.

Wie würdet ihr das Problem angehen? Weiß jemand, wie ich Change Events und Style so miteinander verknüpfe, dass sich bei Änderungen der Style automatisch mitändert?

Viele Grüße!

06.06.2016 - 23:17 Uhr

Servus!

Vll habe ich auch nicht ausreichend recherchiert. Bei mir geht es zwar weniger um die elektrische Darstellung als um die Darstellung der Topologie elektrischer Komponenten samt Leitungsstränge, aber das lässt sich sicherlich übertragen.

Zwischenzeitlich bin ich schon etwas voran geschritten. Ich habe Zooming & Panning in einem kleinen "Prototypen" implementieren können und stecke nun beim Brushing & Linking, was prinzipiell dank den erwähnten Tutorials im Eingangsbeitrag kein Problem darstellt. Nur mit der Koordinatenumrechnung bei verschobenem / skalierten Koordinatensystem tue ich mir grade noch etwas schwer 😉

Mir ist vor Allem wichtig, dass mein Ansatz an sich in die richtige Richtung geht. Vielen Dank für deinen Hinweis zwecks WPF. Vor WPF schrecke ich eig. etwas zurück, da ich bis jetzt kaum Berührungspunkte hatte, unter gewissem Zeitdruck liege und mich dann nochmal on-top komplett in WPF (und die Einbettung in eine WinForms Applikation) einlesen müsste. Ich werde es mir aber überlegen.

06.06.2016 - 18:59 Uhr

Hallo zusammen,

ich habe eine relative spezielle Anforderung und auch nach häufigem Recherchieren bin ich hier noch nicht auf einen guten Lösungsansatz gekommen. Das ist sicherlich auch meiner geringen Erfahrung im Thema 2D-Programmierung geschuldet.

Konkret möchte ich Bordnetze (also einfach gesagt Kabel+Stecker) im 2D vereinfacht darstellen.

Das heißt zunächst einmal:

  • Elektrische Komponenten sind simple Rechtecke.
  • Leitungen sind Linien.

Wichtig sind folgende Funktionalitäten:

  • Zooming & Panning
  • Brushing & Linking, d.h. wenn ich auf ein Rechteck klicke, wird das Objekt grafisch hervorgehoben & mir in der GUI an anderer Stelle der Datensatz hinter dem grafischen Objekt angezeigt.

Größenordnung der Daten:

  • Elektrische Komponenten im 1000er Bereich
  • Leitungen im 1000er Bereich

Angefangen habe ich einfach mal alle Daten einzulesen und diese Daten dann in eine ImageBox zu zeichnen. Das klappt von Performance-Seite her sehr gut.

private void Img_Paint(object sender, PaintEventArgs e)
        {
            // references to object we will use
            Graphics graphicsObject = e.Graphics;

            // Nodes = Rectangle:
            for (int i = 0; i < lstNodes.Count; i++)
            {
                DrawingNode dn = lstNodes[i];
                graphicsObject.DrawRectangle(Pens.Black, dn.x, dn.y, 3f, 3f);
            }
            // Segments = Lines:
            for (int i = 0; i < lstSegments.Count; i++)
            {
                DrawingSegment ds = lstSegments[i];
                graphicsObject.DrawLine(Pens.Black, ds.x1, ds.y1, ds.x2, ds.y2);
            }
            return;
        }

Jetzt geht es aber erst richtig los, denn nun muss ich oben genannte Funktionalitäten umsetzen.

Die beiden Tutorials [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox) und [Tutorial] Gezeichnete Objekte mit der Maus verschieben habe ich mir zu Gemüte geführt bzw bin gerade dabei.

Meine Fragen:

Ist der Ansatz in Ordnung, gibt es hier nennenswerte, bereits vorgefertigte Bibliotheken oder bestimmte Wege, die man gehen sollte?

Vielen Dank im Voraus und viele Grüße!

Edit: Das ganze findet in WinForms statt. Ich finde auf den ersten Blick erstaunlich viel zu dem Thema in WPF, aber ich möchte das ganze später als Modul in ein größeres WinForms Programm integrieren und habe keinerlei WPF Erfahrung.

02.02.2015 - 12:38 Uhr

Super vielen Dank für eure Antworten. Ich melde mich wieder nach Sichten der Ergebnisse.

26.01.2015 - 12:48 Uhr

Hey Leute,

ich brauche als Basis für mein Programm eine simple Drag and Drop Umgebung. Mir fehlen leider die Fachbegriffe, deswegen fällt mir die Suche im Forum/auf Google sehr schwer.

Was ich als Grundlage brauche, ist eine Art "WinForms Designer", also eine 2D-GUI, bei der der Benutzer Symbole, wie z.B. Quadrate, Verbindungen etc. auf eine Art "MindMap" legen kann. Ich muss diese Symbole dann Ansprechen, Verbindungen, Kapselungen etc. auflösen und Logik dahinter legen können.

Ich habe mir überlegt Visio als Grundlage zu nehmen, eine Auswahl an möglichen Elementen (ein paar Standard Fluss Diagramm Shapes, Verbinder usw) vorzugeben und diese dann aufzulösen. Dieser Ansatz wäre allerdings komplizierter, da ich nicht so firm in C# in Verbindung mit Visio bin.

Ich habe XMIND bereits gegoogelt - das ist aber leider WPF - ich bräuchte WinForms.

Habt ihr irgend eine Idee, was es bereits gutes gibt. Ich habe leider nicht die Zeit irgendwas selbst zu entwickeln. Oder würdet ihr mir gar zu Visio raten?

Vielen Dank im Voraus

Grüße!

23.10.2013 - 13:57 Uhr

Hallo,

ich erstelle eine Klasse die von IDisposable erbt und mit einigen Objekten, die ebenfalls davon erben arbeitet, etwa so:

class Test : IDisposable
    {
        public DataTable dataTable { get; set; }
        public Test()
        {
             dataTable = new DataTable();
        }
    }

Meine Frage ist nun: Wenn ich für das Objekt von class "Test" Dispose() aufrufe, muss ich zuvor dataTable disposed haben? Oder geschieht das automatisch?

Also bspw:

Test test = new Test();
test.Dispose(); // test.dataTable wird automatisch disposed

oder:

Test test = new Test();
test.dataTable.Dispose();
test.Dispose();

Danke und Grüße

15.05.2013 - 14:11 Uhr

Hallo zsm,

ich habe eine DataGridView die über eine BindingSource Datengebunden ist. Zusätzlich dazu habe ich noch eine CheckBox-Spalte für den User an den Anfang hinzugefügt, die nicht Datengebunden ist. Werden in dieser Spalte Boxen selektiert verschwinden die Checks in den Boxen, sollte der User die Spalten neu sortieren.

Habt ihr ne Idee, wie man die Checks beibehalten kann?

Grüße!

09.05.2013 - 18:53 Uhr

verwendetes Datenbanksystem: Access 2010

Hallo zsm,

ich habe folgendes Problem:
Ich möchte Visual 2012 in Verbindung mit Access 2010 benutzen (alles 32bit).
Anfangs kam bei "new OleDbConnection("Provider=Microsoft.Jet.OLEDB.14.0; ..." die Fehlermeldung "The 'Microsoft.ACE.OLEDB.14.0' provider is not registered on the local machine" weswegen ich die Office 2010 Access Database Engine (http://www.microsoft.com/en-us/download/details.aspx?id=13255) installiert habe.

Nun führt der Code bis bspw. zum Punkt adapter.Fill() oder connection.open() aus:


        private void Main_Load(object sender, EventArgs e)
        {            
using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.14.0;Data Source=" + AppDomain.CurrentDomain.BaseDirectory + "db1.accdb;Persist Security Info=False;"))
            {

                DataTable dtResult = new DataTable();
                OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM Test", connection);
                OleDbCommandBuilder cb = new OleDbCommandBuilder(adapter);
                cb.QuotePrefix = "["; cb.QuoteSuffix = "]";
                adapter.Fill(dtResult); 
                // ab hier wird kein Code mehr ausgefüllt

            }
        }


        private void Main_Load(object sender, EventArgs e)
        {            
using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.14.0;Data Source=" + AppDomain.CurrentDomain.BaseDirectory + "db1.accdb;Persist Security Info=False;"))
            {

                connection.open();
                // ab hier wird kein Code mehr ausgefüllt

            }
        }

Im Debug Modus "springt" er einfach raus und öffnet die Form (der Code steht momentan in Form_Load()).

Habt ihr ne Idee woran das liegt?

08.05.2013 - 13:21 Uhr

Naja wir werden in diesem Forum nicht zu tief darauf eingehen, da man damit natürlich auch das Gegenteil macht: den Bösewichten helfen. Daher ist sowas ein Thema, in das Du selbst etwas recherchieren solltest.

Klar, kann ich nachvollziehen, hatte nur gehofft ein paar Schlagwörter mitzubekommen um besser Recherchieren zu können.

Und natürlich sind davon alle Spielehersteller und deren Plattformen (Origin, Steam...) davon ebenfalls betroffen.

Ich meinte damit die Haftung / das Thema Schadensersatz. Als Käufer von Spielen die OnlineDRM fordern hat man meines Wissens nach auch keinen Anspruch auf Schadensersatz trotz katastrophaler Launches.

08.05.2013 - 13:18 Uhr

verwendetes Datenbanksystem: <Access / OleDB>

Hey Leute,

Szenario ist, dass ich Daten einer JOIN Anfrage in einem Datagridview visualisieren, um sie vom Nutzer manipulieren zu lassen.

Was ist der richtige Weg, diese Daten wieder upzudaten. Ein einfach adapter.Update(DataTable) funktioniert in diesem Fall ja nicht mehr.

Folgende zwei Überlegungen habe ich angestellt:

  • merged DataTable in Ihre einzelnen Tabellen aufspalten und dann für jede Tabelle ein adapter.Update() fahren
  • merged DataTable durchloopen und "manuelles" Query anlegen "UPDATE ... SET ... WHERE ..." und für jede Row und Tabelle in der DB ausführen

Wie würdet Ihr es angehen? Was ist üblich?

Grüße!

07.05.2013 - 21:30 Uhr

Inwiefern sind dann bspw. Spielehersteller davon nicht betroffen, wie bspw. Sim City 4 (um ein populäres Bsp. zu nennen)?

Trotz der Bedenken interessiert mich das Thema und ich würde gerne mehr darüber erfahren. Eine Abfrage zum Server und das daraus resultierende Ok lässt sich also imitieren? Gibt es da Schlagwörter, die man nachschlagen kann um dem vorzubeugen?

05.05.2013 - 11:36 Uhr

Hallo,

bin dabei eine Internet-App zu schreiben. Da DRM für mich Neuland ist, wollte ich kurz nachfragen, ob folgendes ausreicht oder doch leicht zu umgehen ist:

Da es sich um eine Internet-App handelt, muss so oder so eine Verbindung beim Benutzen bestehen, also würde die App anfangs auf einen Server zugreifen auf dem alle gültigen Keys hinterlegt sind. Ein Key wird für jeden Neukauf angelegt. Ist die Abfrage positiv startet das Programm, falls nicht geht eine Nachricht an den Hersteller o.ä.. Könnte man ja theoretisch noch mit der MAC-Adresse o.ä. kombinieren, falls nur x Lizenzen pro Verkauf erlaubt sind (sodass die App nicht beliebig oft auf beliebig vielen Maschinen mit gleichem Key installiert werden kann).

Ist der Grundgedanke so richtig oder kann man das relativ leicht umgehen?

Grüße

03.05.2013 - 09:08 Uhr

Lust jede Menge, leider muss ich mit den mir gegebenen Vorgaben arbeiten 😃.

Vielen Dank, hab intuitiv auch zum ersten Ansatz tendiert, aber da ich nicht weiß was speziell Access so im Hintergrund macht, war ich mir da unsicher. Dann weiß ich jetzt Bescheid 😃.

03.05.2013 - 08:56 Uhr

verwendetes Datenbanksystem: Access

Hey Leute,

bin gerade dabei eine Oberfläche in C# mit Datenbankenankopplung zu programmieren und muss sehr häufig mit (mehreren) JOINs arbeiten.

Deswegen meine kurze Frage, welcher Ansatz ist richtig?

  1. In meinen JOIN-Kriterien schon von vornherein filtern, welche exakten Datensätze ich letzten Endes möchte, d.h. die "WHERE" Bedingung quasi schon in der "ON" Bedingung aufführen.

  2. Nur die Spaltennamen in die JOIN ON Bedingung packen und zum Schluss mit WHERE den Datensatz den ich will filtern.

Beispiel: 2 Tabellen mit KundenID und gekauftem Artikel, sowie KundenID und Name, man möchte eine Tabelle mit KD-ID, Name und gekauftem Artikel angezeigt bekommen:

 
Tabelle 1:			Tabelle 2:
KD-ID     Artikel	KD-ID 	Name
1            XY		1		Bla
1            Z		2 		Blub
1            P
2            Q
2            I

Ansatz 1: ... JOIN Tabelle2 ON (Tabelle1.KD-ID = Tabelle2.KD-ID AND Tabelle2.Name = 'Bla');

Ansatz 2: ... JOIN Tabelle2 ON Tabelle1.KD-ID = Tabelle2.KD-ID WHERE Tabelle1.Name = 'Bla';

Welcher Ansatz ist nun besser?

29.04.2013 - 08:49 Uhr

Yep, vollkommen ohne Probleme, muss es halt jedes Mal neustarten was sehr nervig ist. Sobald ich z.B. nur eine Neuzeile mehr (also ein "Enter") einfüge kommt dieser Fehler...

Hab jetzt mal sämtliche Klassen in ein neues Projekt kopiert, in der Hoffnung das würde etwas ändern, aber es kommt exakt das selbe Resultat raus. Es ist auch kein Lambda Ausdruck oder ähnliches in der jeweiligen Methode (sonst käme ja auch der entsprechende Hinweis) und egal wo ich den Breakpoint setze, er zeigt mir immer diesen Dialog an.

In jedem anderen Projekt funktioniert das Bearbeiten und Fortfahren problemlos.

Hat ijmd eine Idee?

Edit: Habe gerade die einzige Klasse entfernt in der ich mit dem Excel COM Objekt arbeite... muss also iwas damit zu tun haben. Aber was? Das Objekt ist nur im Code wird aber nicht aufgerufen/erstellt, das Problem tritt schon davor auf...?!

Edit2: Habs: Edit and continue feature stopped working in Visual Studio 2010

26.04.2013 - 11:41 Uhr

Hallo,

ich arbeite momentan an einem Projekt und plötzlich scheint es so, als würde Bearbeiten und Fortfahren im Debugmodus nicht mehr funktioniert.
D.h. wenn ich an einem Breakpoint bin, kann ich keine Änderungen am Code mehr vornehmen und fortfahren, sondern muss das Programm jedes Mal beenden und neustarten.

Die Meldung > Fehlermeldung:

Die Ausführung kann erst fortgesetzt werden, wenn die Kompilierungsfehler behoben werden erscheint - es werden aber keine Fehler angezeigt.

Hat jmd ne Idee woran das liegt?

Gruß

18.04.2013 - 12:56 Uhr

Dann bleib ich wohl bei dem Timer 😃. Damit funktioniert es ja - allerdings halt nicht "punktgenau" zu exakt dem Moment in dem der Inhalt geladen ist.

18.04.2013 - 09:15 Uhr

Prinzipiell weils für mich sehr leicht zu handhaben ist und alle bisherigen Programme wie gewünscht funktionieren. Jetzt stehe ich halt vor diesem Problem, wobei ich denke, dass auch das mit der Webbrowser Control lösbar ist...

18.04.2013 - 08:04 Uhr

Hallo zusammen,

ich rufe via Webbrowser Control eine Seite auf, die Seiteninhalt teilweise mittels JS lädt. D.h. wenn Webbrowser_DocumentCompleted ausgeführt wird, sind diese Inhalte noch nicht vollständig geladen, bzw. gar nicht ausführt, falls Seiteninhalt in einen Frame ausschließlich durch JS geladen wird.

Um den vollständigen Seitenaufbau abzuwarten verwende ich momentan Timer. Das ist wirklich suboptimal 😃.

Ich habe nun das FileDownload Event beachtet. Das löst im Gegensatz zu DocCompleted auch mehrmals aus, wenn Seiteninhalt via JS lädt. Allerdings ist beim letzten Auslösen von FileDownload der Inhalt meist immer noch nicht vollständig da. Also kann ich das auch nicht verlässlich nutzen.

Hat jemand ne Idee, wie man das abfangen kann?

Grüße

21.03.2013 - 08:40 Uhr

Nachtrag:

Sobald sich das Downloadfenster öffnet sind in der Taskleiste (unter Win7) unter dem Programmicon 2 Fenster gebündelt - das eig. Programm und der Download Dialog. Das müsste doch abfangbar sein, sobald sich da ein neues Fenster erstellt?

20.03.2013 - 09:49 Uhr

Ja prinzipiell wie im ersten Post und in meiner Antwort bereits geschrieben, der Downloadlink wird iwie dynamisch erstellt und ist als solcher nicht greifbar.

Ich weiß natürlich durch welchen Seitenaufruf es dann schlussendlich zum Dateidownload kommt (das sind dann iwelche PHP / JS Parameter o.ä. die übergeben werden und es auslösen) aber in Navigating bekommt man nichts vom Downloadlink selbst mit. Weiterhin wüsste ich dann auch nicht wie ich erkenne, dass sich nun das Fenster geöffnet hat / am öffnen ist.

20.03.2013 - 09:05 Uhr

Sry, meinte BeforeNavigate2.

Macht aber keinen Unterschied. Wo soll das sein in C# (nicht VB)?

20.03.2013 - 08:49 Uhr

Hey,

leider gibt es BeforeNavigate als Webbrowser Event nicht (mehr?). Außerdem weiss ich wie der Autor in der Verlinkung nicht über den Dateinamen Bescheid, da dieser nicht direkt im Downloadlink steht.

Gibt es eine andere Möglichkeit? Man kann doch bestimmt generell auch erkennen ob sich irgendwo außerhalb ein bestimmtes Fenster öffnet.

20.03.2013 - 08:14 Uhr

Hallo,

weiß jemand wie ich das Event, das ausgelöst wird sobald der Dialog "Dateidownload" für die Webbrowser Control (also das gleiche was im IE6 beim Klick auf einen Downloadlink passiert) aufpopt abfangen kann oder nur erkennen kann, dass sich dieses Fenster geöffnet hat?

Ich möchte es nicht unterbinden oder sonstiges, ich möchte nur aus dem Programm heraus erkennen können, dass es aufgetaucht ist.

Über das Webbrowser.Filedownload Event geht es nicht, da dieses bei jeder Art von Download auslöst (also permanent während sich eine Seite öffnet) und man keine Möglichkeiten hat zu unterscheiden.

Der Downloadlink ist in meinem Fall nicht direkt verfügbar weswegen Workarounds auch nicht funktionieren.

Ich brauche also wirklich eine Möglichkeit zu erkennen, dass sich das Datei-Downloadfenster öffnet.

Vielen Dank im Voraus und Grüße

17.12.2012 - 09:09 Uhr

Das geht leider beim S3 nicht.

14.12.2012 - 12:25 Uhr

Hat irgendwer Infos zu dem Thema? Oder ne Idee wie man an die Problematik rangehen könnte?

10.12.2012 - 07:48 Uhr

Hey,

sorry, dass ich mich erst jetzt melde.

In Webbrowser.DocumentText steht beim Debuggen die HTML Codierung.

_Edit: Und somit ist die Lösung dann:

string strHtml = WebUtility.HtmlDecode(wBGrab.DocumentText);

_

Edit2: Obige Lösung funktioniert doch nicht. In der gespeicherten Datei werden Sonderzeichen weiterhin falsch angezeigt... ich weiß weiterhin nicht wie ich sie korrekt abspeichern kann.

09.12.2012 - 09:18 Uhr

Danach hab ich ja schon ne Weile gegoogelt, ich finde dennoch nirgends für C# irgend eine Erklärung, wie Dateien kopiert werden.
In zwei Ergebnissen ist ein Verweis auf einen ExpertsExchange Thema, auf das ich keinen Zugriff habe.

Naja sehr schade das Ganze.

08.12.2012 - 23:00 Uhr

Aber das was passiert wenn ich Dateien kopiere und auf dem Handy einfüge (ist ein Galaxy S3, einzige Betriebsmodi: MTC oder PTP (nur Fotos)) muss ich doch irgendwie in C# nachprogrammieren können, mit VS2012 und dem ganzen Schnickschnack der dabei ist.

Da muss es doch irgendeine Bibliothek oder sonst was von Microsoft dazu geben.

08.12.2012 - 12:44 Uhr

Hey,

ich google jetzt schon ne Weile nach der Möglichkeit Dateien zu einem MTP Device zu kopieren (Samsung Handy in meinem Fall).
Die einzige vielleicht passende Lösung liegt auf ExpertsExchange und den Text kann man leider nicht mehr, wie früher, auch unangemeldet anzeigen lassen.

Ich bin bis jetzt nur soweit, dass ich checken kann ob das Handy angeschlossen ist:

 ManagementObjectSearcher deviceList = new ManagementObjectSearcher("Select Name, Status, SystemName from Win32_PnPEntity WHERE Name='GT-I9300'");
            if (deviceList != null)
            {
                foreach (ManagementObject device in deviceList.Get())
                {
                    string name = device.GetPropertyValue("Name").ToString();
                    string status = device.GetPropertyValue("Status").ToString();
                    // ...
                }
            }

Das Handy taucht in der deviceList auf (man bekommt ja nur das Ergebnis von der Select Abfrage zurück).
Wie komme ich jetzt an einen Pfad oder ähnliches, dass ich Dateien rüberkopieren kann - im Prinzip das, was passiert, wenn ich im Explorer Dateien via copy-paste auf das Handy ziehe (im Explorer kann man es ja prinzipiell wie einen USB Stick oder ähnliches öffnen).

Hintergrund ist ein eigenes kleines Tool, das meine Musik auf Handy und USB Stick mit der auf dem PC synchronisiert.

Kennt jmd eine Möglichkeit für C# oder den Befehl den Windows ausführt wenn man Dateien kopiert?

Es funktioniert nicht den Pfad der im Explorer angezeigt wird zu verwenden:

"Computer\GT-I9300"

An den Path komme ich womöglich über: ManagementPath path = device.Path;
Man erhält: "\.\root\cimv2&quot;

Grüße

07.12.2012 - 14:29 Uhr

Hallo,

ich möchte über den Webbrowser aufgerufene Seiten als HTML speichern. Dabei zerreisst es mir die Sonderzeichen. Die Codierung der Seiten ist lt. Header ISO-8859-1:

<?xml version="1.0" encoding="ISO-8859-1"?>
<meta http-equiv="Content-type" content="text/html; charset=ISO-8859-1"/>

Zunächst habe ich die Seite so gespeichert:

 StreamWriter WStream = new StreamWriter(strFileName);
WStream.Write(wBGrab.DocumentText);

Ein "ä" wird dabei aber bspw. zu: �

Dann hab ich folgende Lösung im Inet gefunden:

 StreamWriter WStream = new StreamWriter(strFileName);
System.IO.StreamReader sr = new StreamReader(wBGrab.DocumentStream, Encoding.Default);
string strHtml = sr.ReadToEnd();
WStream.Write(strHtml);

Encoding.Default ist sogar "ISO-8859-1", er schreibt jedoch folgendes in die HTML-Datei: ä (anstelle von "ä";).

Via Rechtsklick->Quellcode anzeigen zeigt mir die Webbrowser Control ein "ä" mittels HTML Codierung an: &#228

Wie kann ich letzten Endes einfach die Sonderzeichen so wie sind abspeichern?

Danke im Vorraus und Grüße

07.12.2012 - 12:59 Uhr

Das bedeutet das Du komische Spaltennamen hast.

Und dein Code Zeigt das du nicht verstehst was da passiert sondern nur Abtippst.

Vollkommen richtig, deswegen frag ich ja hier nach 🤔

...  

Hat geklappt! Vielen Dank!

07.12.2012 - 11:53 Uhr
                        ds.Tables[0].Merge(dtData, true);
                        OleDbCommandBuilder cmb = new OleDbCommandBuilder(da);
                        int count = da.Update(ds); // wirft Syntax error in INSERT INTO statement.

Mit hinzufügen vom CommandBuilder:

"Syntax error in INSERT INTO statement."

07.12.2012 - 11:36 Uhr

Ich steig trotzdem nicht durch... hab mich jetzt am Galileo Comp. Bsp. orientiert:

table1 hat momentan keinerlei Einträge.
In dtData (baugleich mit Access DB Tabelle) liegen die aus der Txt gelesenen Daten.

             using (var connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data source=..."))
                    {
                        connection.Open();
                        OleDbCommand cmd = new OleDbCommand();
                        cmd.Connection = connection;
                        cmd.CommandText = "SELECT * FROM table1";
                        DataSet ds = new DataSet();
                        OleDbDataAdapter da = new OleDbDataAdapter(cmd);
                        da.FillSchema(ds, SchemaType.Source);
                        da.Fill(ds);
                        ds.Tables[0].Merge(dtData, true);
                        int count = da.Update(ds);  // wirft Fehler: "Update requires a valid InsertCommand when passed DataRow collection with new rows."
                     }

da.Update(ds) wirft Fehler: "Update requires a valid InsertCommand when passed DataRow collection with new rows."

06.12.2012 - 20:22 Uhr

Hallo,

ich arbeite mich gerade in C# und Access ein und stehe vor einem Problem.
Ich finde überall Beispiele für das Auslesen von Access DB, aber nirgends passende Ergebnis für die Gegenrichtung.

Hintergrund ist folgender:

Aus einer sehr zerstückelten Textdatei lese ich Daten (-> Tabelle mit ca. 27 Spalten), momentan in eine DataTable. Die Spalten nenne ich im DT-Objekt genauso, wie in der Datenbank.

Welchen simplen Weg gibt es jetzt die fertige DataTable direkt in die Access Datenbank einzupflegen? Da muss es doch eine Möglichkeit geben, ohne im SQL-Befehl sämtliche Spalten angeben zu müssen (à la "INSERT INTO (col1, col2, ...)" zumal ich meinem DT Objekt ja schon extra eben diese Information beigefügt habe und die Spaltenanzahl im DT Objekt natürlich auch gleich der der Access Tabelle ist.

Weiterhin: Gibt es diese Möglichkeit auch für den Fall, dass bestimmte Datensätze schon vorhanden sind, also quasi eine Update Funktion?

Ich stell mir das iwie so vor, dass es eine Funktion zum aufrufen gibt, à la "oleDbCmd.Insert(dataTableObj)"... irgendwas muss es da doch geben.

Vielen Dank schonmal im Voraus und Grüße!

05.09.2012 - 08:09 Uhr

Also wir haben Office 2003, aber dort besteht keine Möglichkeit in Word die Datei als .docx zu speichern. Nur .doc, .xml etc.

Ist halt leider so, Visual Studio 2010 Lizenz aber Office von 2003, weil das halt um einiges kostengünstiger ist.

Ich hoffe es wird dennoch eine Lösung geben.

04.09.2012 - 19:46 Uhr

Ich habe ein Word Dokument "test" erstellt und es als "test.doc" sowie "test.xml" gespeichert (.docx nicht möglich da altes Windows).

Beim Aufrufen beider Dateien durch die Funktion tritt der Fehler "Die Datei enthält beschädigte Daten." auf.

04.09.2012 - 14:14 Uhr

So.. bin jetzt doch nicht zu einer Lösung gekommen. Zu meinem Gedankengang von oben:

Word nummeriert Reihen und Spalten nacheinander, wenn man also einen Zellenverbund in der Mitte oder auf der rechten Seite der Tabelle hat klappt der Trick nicht.

Nun habe ich es via OpenXML versucht, aber ich schaffe es nicht mal eine Datei zu öffnen.
Ich speichere meine Word Datei als xml und öffne sie via:

"WordprocessingDocument.Open()"

erhalte dabei jedoch immer die Fehlermeldung "Die Datei enthält beschädigte Daten." (FileFormatException).

Könnt ihr mir da weiterhelfen?

04.09.2012 - 11:32 Uhr

Achso ok.

Nicht trivial reicht mir 😉 habe jetzt auch eine Möglichkeit überlegt via Interop (nur in der Theorie):

Anm.: Funktioniert nur, falls es für jeden Zellenverbund eine andere Spalte gibt, die ausschliesslich aus einfachen Zellen ohne Verbund besteht.

Ein vertikaler Zellenverbund lässt sich anhand von Sprüngen in der Row-Eigenschaft erkennen (Notation: (Zeile, Spalte)). Bsp.: Zellen (2, 1) bis (4, 1) sind verbunden und (1,1), (5,1) sowie (1,2) bis (5,2) sind einzelne Zellen. Nun durchschleift man sämtliche Zellen in der Tabelle und erkennt einen Sprung von row=2 auf row=5 für alle Zellen mit column=1. Das bedeutet row=2 bis row=4 ist ein Zellenverbund. Jetzt muss eben solange in sämtlichen anderen Spalten nach eben diesen Reihen gesucht werden, bis man eine Spalte findet, in der diese Reihen nicht aus Verbunden bestehen (in dem Fall direkt Spalte 2), greift von diesen Zellen die Höhe ab und summiert sie.

Somit ergibt sich die Höhe des Verbunds.

Das ist jetzt aber extrem nervig zu programmieren, weswegen ich erstmal deinen Rat befolgen und mir die Assembly laden werde. Danke dafür nochmal!

Gruß