Laden...

Forenbeiträge von Mossos Ingesamt 47 Beiträge

24.10.2012 - 10:22 Uhr

@pdelvo
Muss leider .Net 3.5 benutzen, aber trotzdem danke.

@gfoidl
Ich benutzte die WebServiceHost-Klasse für meinen WebService. Die Antwort vom Server wird einfach an den Client zurück geliefert.

23.10.2012 - 17:15 Uhr

Bei der Queue hab ich mich an die SyncQueue < T > von herbivore gehalten.

Wieso sollte es nicht funktionieren? Ich habe für SendMessage bis jetzt nur ne Dummy-Methode benutzt, aber damit klappt es. Woran könnte es denn scheitern? Ich werde in der Methode natürlich darauf achten, dass sie irgendwann abbricht, falls sie vom EndServer keine Antwort bekommt.

EDIT: Ach jetzt hab ich erst verstanden was du gemeint hast. Ne also SendMessage ist eine Methode die den Message-String von dem Message-Objekt an einen Server schickt und dessen Antwort-String zurückgibt. Diese Methode wartet nicht auf ein Event. Oh ja die Namensgebung ist etwas irreführend ^^ Sorry, ich verbesser das.

23.10.2012 - 16:39 Uhr

Ja das ganze Projekt ist auch recht umfangreich.
Vom Webservice trudeln halt immer wieder Nachrichten ein, die der Server an einen anderen Server weiterleiten muss (mit den Mindestabständen). Die Antwort des Server muss dann wieder vom Server zurück an den Webservice gegeben werden.

Ich habs aber jetzt gelöst bekommen.
Wie du gesagt hast, reihe ich jetzt die Objekte mit der Nachricht in die Queue ein. Den Objekten übergebe ich ein AutoResetEvent im Konstruktor und warte in der Methode des WebServices auf das Event (mit WaitOne).

Ein separater Thread überwacht die Queue, und sendet nach der Reihe die jeweilige Nachricht in den Objekten. Die Antwort des Servers wird in ein Resultattribut des Objektes zurückgegeben und gleichzeitig das Event ausgelöst. Anschließend wird der Thread für ne kurze Zeit schlafen gelegt.


//Die Methode im WebService
public Result ExecuteCommand(string command)
{
   AutoResetEvent ev = new AutoResetEvent(false);
   Message m = new Message(command, ev);
   messageQueue.EnqueueMessage(m);

   ev.WaitOne();
   return m.Result;
}

//Message-Klasse
....
public void ApplyResult(string result)
{
     this.result = result;
     //Löse event aus
     AutoEvent.Set();
 }

//MessageQueue-Klasse
....
public void enqueueMessage(Message m) { ... }

//Wird im separatem Thread ausgeführt
public void monitorQueue()
{
    while (currentState == State.running)
    {
          if (queue.Count > 0)
          {
                Message m = queue.Dequeue();
               
                //SendMessage schickt die Nachricht an den "End-Server" und gibt die Antwort zurück
                string result = SendMessage(m.Message);
                m.ApplyResult(result);

                //Der Mindeszeitabstand zwischen 2 Nachrichten
                Thread.Sleep(2000);
          } else
          {
                Thread.Sleep(100);
          }
     }
}

(Hab ein bisschen abgekürzt)

Ist das jetzt zu kompliziert?
Statt dem Thread.Sleep(100) könnte man jetzt nen Timer benutzen, aber macht das irgendeinen großen Unterschied?

Danke für die Antworten!

Gruß,
Mossos

23.10.2012 - 09:42 Uhr

Oh sorry herbivore, hab deinen Post übersehen ^^.
SyncQueue hatte ich mir schon angeguckt, sieht gut aus. Aber ich weiß nicht ob das so mit den Objekten funktioniert.
Also ich muss dazu sagen ich lasse einen Webservice laufen. Der Benutzer geht auf einen Link, was im Code eine Methode aufruft, die dann eine Nachricht sendet und auf eine Antwort wartet. Die Antwort ist dann der Rückgabewert der Methode. Das heißt ich müsste in der Methode auf das Ergebnis warten. Mit Events geht das ja schlecht.

EDIT: Oh ich denke das müsste mit WaitOne() funktionieren oder?

23.10.2012 - 09:30 Uhr

Hm gibts zur Task Klasse auch eine Alternative? Auf dem Server, auf dem die Anwendung laufen wird ist nur .Net 3.5 installiert.

Zum Timer: Was spricht eigentlich dagegen, den Thread nach jedem Methodenaufruf für die gewisse Zeit schlafen zu legen? Beim Timer müsste ich das doch auch machen, weil ich nicht will, dass er nur z.B. alle 2 Sekunden überprüft, ob eine Methode ausgeführt werden soll. Das sollte schon schneller gehen. (Die Methoden werden nicht kontinuierlich ausgeführt)

22.10.2012 - 16:30 Uhr

Hallo zusammen,

ich hab folgendes Problem:
Verschiedene Objekte sollen Nachrichten über das Netzwerk an einen bestimmten Endpunkt senden und bekommen auch wieder eine Antwort zurück. Allerdings sollen die Nachrichten nacheinander und zwar in bestimmten Mindestzeitabständen gesendet werden, z.B. zwischen zwei Nachrichten müssen immer min. 2 Sekunden liegen.

Ich hatte mir jetzt gedacht, dass ich die Methoden in einer Queue einreihe und die dann nacheinander abarbeite, habe aber noch keinen vernünftigen Ansatz gefunden das zu realisieren. Das Problem war immer den Rückgabewert an die aufrufende Methode zurückzuschicken.

Ich hab z.B. versucht die Methoden (die die Nachrichten senden) in Delegates zu packen und die dann in eine Queue einzureihen. Permanent würde dann ein Thread die Queue abfragen, ob Nachrichten zu senden sind und wenn ja die Methoden dann nacheinander ausführen. Aber wie gesagt, habe ich keine Ahnung wie ich dann den Rückgabewert an das Objekt zurückzuschickensoll, welches die jeweilige Methode aufgerufen hat.

Hat da jemand vielleicht nen vernünftigen Ansatz?

28.03.2012 - 18:22 Uhr

Die aktuell sichtbaren Elemente erhälst du mit: dataGridName.ItemContainerGenerator
Das DataGrid muss dabei natürlich die Virtualisierung eingeschaltet haben sonst sind alle Elemente da drin 😉

28.03.2012 - 17:54 Uhr

Hi!
Geht das nicht einfach, indem du die Spaltenbreite in WPF dynamisch angibst, also mit dem "*" ? Dann sollten sich die Spalten doch automatisch anpassen..

24.02.2012 - 23:53 Uhr

Musst du nicht einfach nur das Projekt angeben?
Also so: ImageSource="pack://application:,,,/MyApp;component/Images/topbanner_bg.png"

oder: ImageSource="pack://application:,,,/ClientView;component/Images/topbanner_bg.png"

ich weiß jetzt nicht, wie dein Projekt in der .dll heißt.
Ich habs zb bei mir so:
"pack://application:,,,/ProjektFromDll;component/images/image.png"

Gruß,
Mossos.

24.02.2012 - 00:30 Uhr

AAh! Ich hab endlich rausgefunden was beim ScrollViewer mit Offset gemeint ist 🤔 (Position der Scrollbar, 0 = ganz oben, [Wert von ScrollableHeight] = ganz unten)
Also man kann nun z.B. wenn das Event **ScrollChanged **gefeuert wird überprüfen, ob VerticalOffset = ScrollableHeight ist. Dann kann ich die nächsten Ergebnisse laden.
Allerdings funktioniert das nicht mit dem, in der ListView integrierten ScrollViewer, weil dieser diese Properties nicht besitzt. Die ListView muss in den "normalen" ScrollViewer eingebettet werden.
Dann hat man wiederum das Problem, dass das Scrollen per Mausrad nicht mehr ohne weiteres funktioniert, wenn die Maus über der ListView positioniert ist...

Danke für die Ideen.

Gruß,
Mossos.

23.02.2012 - 00:07 Uhr

Ja ich hätte ja auch nur gern das Prinzip nachgemacht, nicht die genaue Funktionsweise.
Ich hab hier nur noch keinen Ansatz gefunden, zu erkennen, dass das letzte Element wirklich sichtbar für den Benutzer ist.

Aber wenn sowas zu kompliziert zu realisieren ist....

22.02.2012 - 22:55 Uhr

Das wäre so wie bei Facebook 😄

Ich mein so irritierend ist das doch eigentlich nicht für den Benutzer find ich. Wenn der Benutzer alle Ergebnisse sehen will, muss er ja in jedem Fall nach unten scrollen und dann werden neu Ergebnisse angezeigt.

Also mit dem Programm kann man die Google-Suche benutzen (mit der Google-Api). Mit einer Suche kann man leider immer nur 8 Ergebnisse erhalten, daher muss man die bereitgestellte Such-Methode öfters ausführen. Das Problem ist aber, dass man die nicht zu schnell hintereinander ausführen darf, weil sonst ein "Abuse" angenommen wird. Und wenn man in einer gewissen Zeit recht oft die Suche startet, muss man komischerweise irgendwann längere Pausen zwischen den Suchen machen, damit nicht wieder so eine "Abuse-Exception" kommt -.-
Deshalb wird im Moment nur nach neuen Ergebnissen gesucht, wenn man nach unten scrollt.

22.02.2012 - 21:29 Uhr

Nabend zusammen!

Ich habe eine ListView die an eine ObservableCollection gebunden ist.
Anfangs werden eine bestimmte Anzahl an Items in die Collection geladen und wenn man die ListView nach unten scrollt - also zum letzten Element - sollen der Collection neue Items hinzugefügt werden.
Im Moment habe ich das so gelöst:


Control lastRow = resultViewList.ItemContainerGenerator.ContainerFromItem(resultList[resultList.Count - 1]) as ListViewItem;

if (lastRow != null)
{
     //Do action
}

Das funktioniert auch, allerdings nur solange ScrollViewer.CanContentScroll="True" ist (Wird ja sonst die ganze Collection in den ItemContainerGenerator geladen).
Ich hätte aber diese Eigenschaft gerne auf False, weil das hier besser aussieht.

Hat jemand ne Ahnung, wie ich jetzt prüfe, ob die ListView ganz nach unten gescrollt ist?

Gruß,
Mossos.

19.01.2012 - 13:52 Uhr

Um das Vernünftig zu machen musst du dir wohl oder übel nen paar basics in SQL anschaffen. Hört sich jetzt aber nicht kompliziert an was du haben willst. Ne Abfrage nach nem Datum oder nem Textwert ist ziemlich leicht in SQL zu realisieren, und halt auch schnell.

19.01.2012 - 09:00 Uhr

Wie kann ich eigentlich eine exe Datei bzw eine Installation erstellen? Der Doppelklick auf die exe Datei bei mir klappt, aber natürlich nicht bei einem anderen Rechner.

Z.B: Build/Publish [Projektname]
Ansonsten kannste auch die .exe aus dem Release ORdner nehmen (Debug würde auch gehen). Du musst aber auch evtl erstellte Assemblies etc. auf die in deinem Programm verwiesen wird mitnehmen. Außerdem, wenn dein Programm auf ne Datenbank zugreift, sollte der andere PC auch auf die Datenbank zugreifen können und wenn nötig den SQLConnector installiert haben (je nachdem was du für ne Datenbank benutzt).
Den am anderen PC auftretende Fehler solltest du notfalls debuggen.

Dann müßte ich die EInschränkunen nicht über ein SQL COmmand treffen, sondern könnte die Abfragen durch das Hinzufügen von Funktionen und Klassen vereinfachen (bin kein SQL-Freak).

Was meinst du denn für Einschränkungen?
Generell ist SELECT * FROM... nicht so performant, als wenn man direkt die gewollten Spalten angibt.
Falls du trotzdem nur bestimmte Spalten aus deiner DataTable angezeigt haben willst, musst du die Spalten in WPF selbst erzeugen und "AutoGenerateColmns = False" setzen.
Die einzelnen Spalten bindest du dann an den jeweiligen Spaltennamen der Tabelle aus der Datenbank.

16.01.2012 - 18:36 Uhr

Nabend!
Du musst ja schon erstmal die DataTable füllen. Das machste mit dem SqlDataReader. Und die DataTable dann einfach ans DataGrid binden.

Gruß,
Mossos

09.01.2012 - 10:48 Uhr

Ah super danke! Funzt super. Musste allerdings noch nen kleinen bug beheben, da es passieren konnte, dass er zu viel laden wollte, wenn die pageSize nicht genau durch die Anzahl der Zeilen teilbar ist (Also 999 Zeilen, pageSize = 50 versucht er ganz unten 50 statt 49 zu laden).
Hab daher noch die LoadPage Methode geändert:


private void LoadPage(int pageIndex)
        {
            int currentPageSize = _pageSize;
            int startIndex = pageIndex * _pageSize;

            if (_list != null && _list.Length - 1 < startIndex + _pageSize)
            {
                currentPageSize = _list.Length - startIndex;
            }
            LoadRange(startIndex, currentPageSize);
        }

06.01.2012 - 16:28 Uhr

Ja find ich auch. Aber ich wüsste nicht wie ich da ne BlockingCollection einbauen soll. Diese VirtualList wurde ja selbst implementiert. Ich kann die jetzt nicht einfach durch ne andere Collection ersetzen, weil mir dann ja die ganzen Funktionen fehlen..

06.01.2012 - 12:40 Uhr

Das mit dem Overhead hab ich schon beim Laden rausgenommen.
Das andere guck ich mir mal an.

Allerdings denk ich, dass das nicht mit meinem Problem zusammenhängt, weil er manchmal wirklich garnichts mehr macht. Ich scrolle und irgendwann bleibt alles stehen. Die CPU-Last ist bei 0, also rechnet der ja auch nichts. Das Programm kommt auch nicht wieder zurück.
Wenn ich dann mal im Visual Studio auf Break klicke, steckt der im QueuedBackgroundWorker fest:


public void Add(T workItem)
        {
            lock (this)     // <= Hier
            {
                if (_queue.Contains(workItem))
                    return;
                _queue.Enqueue(workItem);
                if (State == QueuedBackgroundWorkerState.Standby)
                    State = QueuedBackgroundWorkerState.Processing;
            }
        }

06.01.2012 - 11:04 Uhr

klein ist gut... ^^
Ich hab einfach nur diese virtualisierte ListView getest, die xxMUROxx hier verlinkt hat.
WPF Data Virtualization
In dem Projekt ist eine Demo enthalten, mit der man sich diese WPF Data Virtualization angucken kann. Da beim scrollen kommt es irgendwann zum deadlock, wenn viele Elemente hintereinander geladen werden.
Es wird mit einem Backgroundworker gearbeitet und da hängt er dann auch irgendwo.

Das Projekt ist schon etwas umfangreicher, deshalb weiß ich nicht, was ich davon hierein stellen kann.

06.01.2012 - 09:13 Uhr

Das hängt davon ab wie viel du beim Erstellen der VirtualList eingestellt hast.

Ist das die DefaultPageSize bzw. die pageSize im VirtualList-Konstruktor?

Hab die Animation mal rausgenommen.
Hab aber noch ein Problem: In der Demo kommt es beim Scrollen immer wieder zu Deadlocks. Auch schon bevor ich da im Code was umgestellt habe. Das einzige was umgestellt ist, ist ScrollViewer.IsDeferredScrollingEnabled="False"
Selbst wenn ich das auf "True" gelassen habe und mit dem Scrollrad scrolle, tritt der Deadlock irgendwann auf..

Ist das bei dir auch?

04.01.2012 - 12:20 Uhr

Hm ich denke mal, der Schlüssel liegt in ** ScrollViewer.IsDeferredScrollingEnabled="True"** (Wie es auch in Outlook benutzt wird)

Bei diesem VirtualCanvas ruckelt es auch, wenn ich schnell hin und her scrolle.

Hab mir dann auch mal DevZest - Wpf Data Virtualization angeguckt. Wenn man in der Demo der ListView mal ein paar Checkbox-Spalten hinzufügt und ScrollViewer.IsDeferredScrollingEnabled="False" setzt, muss dauernd neu geladen werden. Außerdem finde ich die Ladeanimation ziemlich störend, wenn die während dem Scrollen erscheint. Für das erstmalige Laden der Daten allerdings nicht schlecht!
Danke dafür!

28.12.2011 - 18:19 Uhr

Danke für die Antwort!
Ich werde das mal ausprobieren.

Gruß,
Mossos.

22.12.2011 - 09:29 Uhr

Wirklich niemand ne Idee??

Mir ist aufgefallen, dass die Häkchen in den CheckBoxes erst gesetzt werden, wenn die Checkboxes auch im Window sichtbar werden (also wenn man z.B. runter scrollt). Mir scheint aber, dass die Checkboxes an sich nicht erst gezeichnet werden wenn sie zu sehen sein müssten, d.h. sie werden wohl nicht virtualisiert, sondern werden direkt alle aufeinmal gezeichnet.
In der Tat kann man das Fenster so klein wie möglich machen, die Performance nimmt dadurch nicht zu. Bei einer korrekten Virtualisierung, sollte es dann ja schneller gehen, weil nicht so viel gezeichnet werden muss.

Weiß jemand vielleicht, wie man es hinbekommt, dass die Checkboxes korrekt virtualisiert werden?

Also falls jemand das vielleicht mal selber testen mag und zu faul ist das selber zu schreiben, kann ich das Projekt auch gerne bereitstellen 😃

Gruß, Mossos.

EDIT: Hm, ich hab die Checkbox-Property Visibility="Hidden" gesetzt, aber die Performance wird trotzdem nicht besser 😦 liegt also doch nicht an dem neu zeichnen...was ist das bloß?

19.12.2011 - 15:14 Uhr

Hallo zusammen!

Ich habe eine kleine Anwendung geschrieben, um die Performance zwischen DataGrid und ListView zu vergleichen.

Ich habe im ersten Test 2000 Zeilen mit 18 TextSpalten generiert.
VirtualizingStackPanel.IsVirtualizing="True" ist gesetzt.

Hier hat die ListView noch eine ganz gute Performance beim Laden der Daten sowie beim hoch und runter scrollen. Das DataGrid ist da schon deutlich langsamer.

Nun habe ich noch 6 Spalten bestehend aus CheckBoxes hinzugefügt und die Scroll-Performance bricht total ein.

Ich hab schon etliche Foren durchsucht, relativ viel zu dem Thema gefunden, nur leider keine Lösungen.
Hat hier vielleicht jemand ne Idee das DataGrid oder die ListView hinsichtlich des Scrollens performant zu bekommen??

Hier noch nen bisschen Code, wie ich die Checkboxes in die ListView eingebaut habe:


<Grid.Resources>
            
            <DataTemplate x:Key="comboBoxTemplate">
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding Path=boool}" />
                </StackPanel>
            </DataTemplate>
        </Grid.Resources>


<ListView Name="listView1" VirtualizingStackPanel.IsVirtualizing="True">
                        <ListView.View>
                            <GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Employee Information">
                                <GridViewColumn CellTemplate="{StaticResource comboBoxTemplate}"  Header="ComboBox" Width="75" />

[...]

Gruß,
Mossos.

17.12.2011 - 01:51 Uhr

Ich weiß jetzt nicht ganz, ob ich verstanden habe, was du willst...

Willst du in dem internen Datagrid (also das datagrid in der Übersichtsspalte) nur Zeilen, in denen die Fahrzeug_ID gleich der ID der "Hauptzeile" ist?

Sind deine Items, die in dem DataGrid angezeigt werden Objekte? Wenn ja, füge den Objekten einfach eine ObservableCollection (oder ne andere Collection, die das interne Datagrid binden kann) hinzu und pack da die gewünschten Objekte rein, also die die zu der Fahrzeug_ID passen.

Das interne DataGrid wird dann an die jeweilige ObservableCollection.

Hoffe ich hab das so richtig verstanden und hab das nicht zu kompliziert erklärt ^^

10.10.2011 - 09:39 Uhr

Das Anzeigen mache ich auch so. Ich benutze in WPF einen DateConverter, indem das DateTime aus der Datable mit ((DateTime)value).ToShortDateString() umgewandelt wird.

Ähh das Problem war ein anderes. Hab in den Parameterangaben des MySqlAdapters noch VarChar, statt DateTime stehen gehabt 😛 da hätt ich auch früher drauf kommen können...grml

Trotzdem Danke!

10.10.2011 - 09:10 Uhr

verwendetes Datenbanksystem: MySql Version: 5.5.11

Moin zusammen!
Ich habe ein DataTable, die Datensätze aus einer MySql-Tabelle ausliest und dann mittels DataGrid angezeigt werden. Die Informationen erhält die DataTable über einen MySqlDataAdapter. Änderungen im DataGrid werden auch über den MySqlDataAdapter an MySql übergeben.

In der MySql-Tabelle hab ich zwei DateTime-Spalten. Die Werte im DataGrid werden in diesem Format angezeigt: DD.MM.YYYY, also anders als in MySql.
Man kann die Datums-Werte im DataGrid über DatePicker eingeben. Mit einem Klick auf einen Speichern-Button werden die Änderungen dann an die MySql-Tabelle übermittelt.

Nun zu meinem Problem:
MySql erwartet ja immer das Format: YYYY-MM-DD. Wenn nun das Datum vom DatePicker in dem anderen Format übergeben wird, kommt es zu komischen Datums-Werten in der MySql-Tabelle. Oder im schlimmsten Fall sogar zu ungültigen Werten.

Gibt es da irgend eine Möglichkeit, die Datumswerte vernünftig in die MySql-Tabelle zu schreiben? Ich möchte gerne das Format DD.MM.YYYY im DataGrid beibehalten.

Gruß,
Mossos.

22.09.2011 - 17:09 Uhr

in meiner app.config hab ich keinen solchen Eintrag..
Liegt das daran, dass die Exception kommt?

EDIT:
Ahhh Tatsache...klappt nun. Das hier in die app.config:


<system.net>
    <defaultProxy enabled ="false">
      <proxy autoDetect ="True"/>
    </defaultProxy>
  </system.net>

22.09.2011 - 17:00 Uhr

Blöde Frage aber wo find ich die Konfigurationsdatei??

22.09.2011 - 16:26 Uhr

Hallo zusammen!

Ich hab ein Programm erstellt, mit dem man über ein HttpWebRequest eine Datei auf einen Server hochladen kann.
Als Administrator, bzw wenn man das Programm Als Administrator ausführt funktioniert das auch. Wenn man allerdings keine Administratorrechte hat und somit nicht als Administrator ausführen kann, kommt beim Upload folgende Fehlermeldung:

Fehlermeldung:
Fehler beim Erstellen des Webproxys, der im Konfigurationsabschnitt system.net/defaultProxy angegeben ist

Code:


HttpWebRequest HttpRequest = (HttpWebRequest)WebRequest.Create(this.fullUrl);

this.fullUrl ist z.B. : http://url.de/datei.txt

Wieso braucht man Adminrechte um ein HttpWebRequest zu erstellen und was kann man dagegen tun? Das ist doch voll dämlich oder?

Gruß,
Mossos.

19.09.2011 - 16:08 Uhr

Aso okay, schau ich mir mal an. Dankö!

15.09.2011 - 14:04 Uhr

Hm also ich habs jetzt:


DataSet clients;
DataGrid clientGrid;

.....


DataRow[] foundRows;
foundRows = clients.Tables[0].Select(expression);

foreach(DataRowView dr in clientGrid.Items)
{
     if (dr.Row == foundRows[0])
     {
           clientGrid.ScrollIntoView(dr);
           break;
     }
}

Also müsste man dann noch etwas erweitern für mehrere Ergebnisse, bzw wenn nichts gefunden wird.
Hatte gedacht es gäbe eine elegantere Lösung, als jede Zeile abzuklappern, aber bei eine DataGridgröße von so 1500 Zeilen kommt man unter einer Sekunde ans Ende.

Falls doch noch jmd ne bessere Lösung hat, würd ich die trotzdem gerne sehen. 😃

15.09.2011 - 13:35 Uhr

Ich befülle das DataSet/DataTable mit einem SqlAdapter:


DataSet clients = new DataSet();
MySqlDataAdapter da = SqlHandler.GetTableFromDB(columns, tablename);
da.Fill(clients);

clientGrid.ItemsSource = clients.Tables[0].DefaultView;
clientGrid.DataContext = clients.Tables[0];

15.09.2011 - 12:25 Uhr

ja da hab ich das problem, dass sich der index des items in der gebundenen datatable mit dem index im datagrid unterschiedet, wenn man das datagrid nach einer Spalte sortiert.

15.09.2011 - 12:20 Uhr

Mit DataSource meinst du doch zb nen DataSet, etc. was an das dataGrid gebunden wird oder? Das wär ja mein DataSet, in dem ich nach dem Begriff gesucht habe.
Wenn ich das Ergebnis den SelectedItem zuordne wird nichts selektiert, weil ein DataRowView erwartet wird (und keine DataRow). 😦

15.09.2011 - 11:49 Uhr

Hi!
Hab schon wieder ne Frage 😛
Hab die ganze Zeit schon gesucht, aber nichts vernünftiges gefunden..
Ich möchte in eine Textbox einen Begriff eingeben und nach Klick auf einen Button soll das DataGrid zur nächsten gefunden Zeile mit dem Begriff scrollen.
Das DataGrid bezieht die Informationen von einem DataSet.

Ich hab nun versucht erstmal die Zeile zu finden. Hab dann im DataSet danach gesucht und einen Array aus DataRows erhalten.


DataRow[] foundRows;
 foundRows = clients.Tables[0].Select("displayname Like '%" + tb_search.Text + "%'");

Das Problem ist jetzt, die jeweiligen Datarows mit den Items im dataGrid zu vergleichen, damit an die richtige Stelle gescrollt wird, da die Items ja DataRowViews sind.
Ich hab im Netz eine Methode gefunden, für die DataRow eine DataRowView zu erhalten:


DataRowView drw = foundRows[0].Table.DefaultView[foundRows[0].Table.Rows.IndexOf(foundRows[0])];

Das ist aber Käse, wenn man das DataGrid nach irgendwelchen Spalten sortiert, weil die Indexe dann nicht mehr übereinstimmen.

Zum Scrollen benutze ich übrigens:


clientGrid.ScrollIntoView(drw);

Hat jemand ne Idee, das umzusetzen?

Gruß,
Mossos.

14.09.2011 - 16:28 Uhr

Tag zusammen!
Ich habe ein DataGrid, welches ihre Daten von einem DataSet bezieht.
Das Löschen von Zeilen ist aktiviert, aber es dürfen ein paar bestimmte Zeilen nicht gelöscht werden (diese sind fix: z.B. die Zeilen die in Spalte eins den Wert "x", "x" oder "z" haben).

Hat jemand ne Ahnung wie das zu realisieren ist?

Gruß,
Mossos.

30.08.2011 - 16:42 Uhr

Ah super danke!

Hab das dann in der Konstruktor geschrieben:


KeyBinding CopyBinding = new KeyBinding(ApplicationCommands.NotACommand, Key.C, ModifierKeys.Control);

dataGrid.InputBindings.Add(CopyBinding);


30.08.2011 - 15:43 Uhr

Hallo zusammen.
Ich habe ein DataGrid, bei dem es die Möglichkeit gibt, die Spalte X aus einer oder mehreren Zeilen zu kopieren. Dafür hab ich zum einen einen Button, auf den man klicken muss.
Zum anderen möchte ich aber auch, dass man das mit Strg+C machen kann, weil sonst die ganze Zeile und nicht nur der Wert dieser Spalte in die Zwischenablage kopiert wird.

Jetzt hab ich versucht mit dem Event PreviewKeyDown und KeyDown zu arbeiten, allerdings werden die anscheinend überschrieben von der Windows-eigenen Strg+C-Funktion.


private void dataGrid_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.C && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
            {
               //In die Zwischenablage kopieren
            }
        }

Hab hier schon einige Threads durchsucht, aber nciht so wirklich was gefunden, was mir hier weiterhilft 😕

MfG
Mossos

25.08.2011 - 20:13 Uhr

normalerweise hat die WPF- Progressbar keine Refresh-Methode. Aber dafür hab ich ja die ExtensionMethod.. ^^ Kann man dann halt mit jedem UIElement benutzen.

Ich find diese Lösung bequemer als die Thread-Lösung. Kommt aber auch immer auf die Situation an..

25.08.2011 - 20:04 Uhr

Doch, doch die macht was. Ich habs nun geschafft.
Ich musste nur das Event kennen, das geworfen wird, wenn sich der Wert der gebunden Variable ändert.


ProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
      if (sender is ProgressBar)
            {
                ((ProgressBar)sender).Refresh();
            }
}

So werden die progressbars direkt geupdated und nicht erst, nachdem die Schleife durchlaufen wurde. Hurra ^^

25.08.2011 - 19:41 Uhr

Klar kommt die raus ^^ hab ich nur gemacht um die GUI zu testen.

Also ich weiß, dass normal mit den Threads gemacht wird, aber ich hab die Refresh-Methode ja erweitert, wodurch sich die progressbar direkt aktualisiert wird.


public static class ExtensionMethods
    {
        private static Action EmptyDelegate = delegate() { };

        public static void Refresh(this UIElement uiElement)
        {
            uiElement.Dispatcher.Invoke(DispatcherPriority.Background, EmptyDelegate);
        }
    }

Da ist halt nur die Frage, wo man den Refresh ausführt..
würde mir was Arbeit ersparen 😛

25.08.2011 - 19:10 Uhr

Danke! Das hat shconmal geklappt.


public event PropertyChangedEventHandler PropertyChanged;

public int progressValue { get; set; }

public int progress 
{
            get { return this.progressValue; }

            set
            {
                if (value != this.progressValue)
                {
                    this.progressValue = value;
                    NotifyPropertyChanged("progress");
                 }
             }
}

private void NotifyPropertyChanged(String info)
{
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
}

JEtzt werden die Progressbars allerdings noch nicht direkt aktualisiert, sondern erst nachdem meine obige for-schleife durchlaufen ist.
Wie bekommt man es denn mit, dass sich was an den gebundenen Daten verändert hat, damit man selber die ProgressBar refreshen kann?
Ich hatte es versucht mit:

Binding.SourceUpdated="ProgressBar_SourceUpdated"

in den ProgressBar Properties, aber das Event wird nicht geworfen wenn sich der progress-Wert ändert...

25.08.2011 - 17:43 Uhr

Hallo zusammen!
Ich habe ein DataGrid, in die eine ObservableCollection gebunden wird. Die Collection besteht aus "FileItem"-Klassen, die ein paar Eigenschaften haben.
Die Eigenschaften werden dann an die einzelnen Spalten des DataGrids gebunden, unteranderem eine Progressbar.
Der Value der Progressbar ist von der FileItemEigenschaft "progress" abhängig.

Nun sollen die Dateien, die von den FileItems repräsentiert werden hochgeladen werden. Dabei wird "progress" hochgezählt.

Ich möchte jetzt, dass die ProgressBar immer dann ihren Wert aktualisiert.

Ich habe dafür schon die Refresh-Methode überschrieben, sodass die Bar nicht erst am Ende des Uploads aktualisiert wird. Allerdings tut sich überhaupt nichts an der Progressbar.

Hier mal ein bisschen code:


//DataGrid
<DataGrid AutoGenerateColumns="False"  ItemsSource="{Binding fileCollection}" Name="dg_FilesToUpload" SourceUpdated="dataGrid1_SourceUpdated">
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
                <ProgressBar Height="5" Maximum="{Binding size}" Binding.SourceUpdated="ProgressBar_SourceUpdated" Value="{Binding progress}"/>
         </DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>


//Die Methode die den Upload simulieren soll

public FileItem UploadFileTest()
        {
            for (long i = 0; i < 50; i++)
            {
                file.progress += 200;
                Thread.Sleep(10);
            }
            return file;
        }


//Die FileItem Klasse

class FileItem
 {
        public String filename { get; set; }
        public long size { get; set; }
        public long progress { get; set; }    

public FileItem(String filename, long size, long progress)
{
...
}
...
}

Geh ich das ganze falsch an oder gibts da ne einfache Möglichkeit, das so zu lösen?
Wenn ihr noch irgendwelchen Code braucht, sagt bescheid 😛

Gruß, Mossos.

20.08.2011 - 13:11 Uhr

Hallo zusammen!

Ich habe in Problem bei der Datenübertragung von: Excel -> C# -> MySQL

Folgende Situation:
In C# lese ich mit Interop.Excel ein 2dimensionales Array einer .xls-Datei ein. Anschließend, nach kleiner Umstrukturierung der "Spalten", schreibe ich die Daten (parametrisiert) in eine MySQL-Datenbank (innoDB, Zeichensatz Latin1 (bzw. auch getestet mit UTF-8 default); MySQL 5.5.17.
Dies klappt so eigentlich einwandfrei. Umlaute werden richtig in die Tabelle geschrieben, keine Probleme erstmal.

Nun im nächsten Schritt lese ich wieder Daten eines anderen .xls-Dokumentes ein und möchte dann auf die eben gefüllte Datenbank-Tabelle Updates ausführen.

UPDATE tabelle SET spalte1 =@p1 WHERE name=@p2
(@p1, @p2 halt irgendwelche Parameter)

Hab ich dann irgendwann für @p2 z.B. den Namen "Müller" stehen, bekomme ich eine MySQL-Exeption. Dadrin sieht man, dass das "ü" nicht richtig dargestellt wird, sondern in zwei kryptischen Sonderzeichen. (Genaue Fehlermeldung kann ich leider erst Montag geben, wenn ich wieder im Büro bin 😕)
Ich hab dann mal vor dem SQL-Statement nen Breakpoint gesetzt, und mir die values angeguckt. Dort wurden die Umlaute noch richtig angezeigt.

Find ich alles sehr seltsam, hat irgendjemand ne Idee woran das liegen könnte, oder weiß jemand wie man das beheben kann?

Gruß,
Mossos.