Wenn Du auf COM/Interop benutzt, dann musst Du dynamic und nicht var zum typisieren benutzen.
Der Hintergrund ist, dass die Typisierung von var zur Compile-Zeit erfolgt, die Typisierung von dynamic hingegen zur Laufzeit - wie auch COM funktioniert.
Das erklärt schön dieser MSDN-Artikel.
Wenn Du an fortgeschrittenen Techniken interessiert bist, dann würde ich mir mal den TailBlazer anschauen.
Das Scrollen und besonders die Suchbefehle gehen wirklich schnell.
Du musst nicht mehrfach kompilieren, der Compiler setzt ein Flag, was festlegt, ob die .NET Runtime einen 32 oder 64 Bit Prozess startet.
Elegante Lösungen gibt es nicht, da das auf Betriebssystem-Ebene so festgelegt ist - siehe hier.
Das mit dem Kompilieren ist auch ein Irrglaube.
Ob die .NET Runtime etwas mit 32 oder 64 Bit ausführt, steht im Portable Header.
Mit Corflags kannst Du jederzeit den PE Header ändern.
Du verwechselst gerade 2 Dinge.
Für das dynamische Aktualisieren einer Bindung brauchst Du INotifyPropertyChanged unabhängig ob Klasse oder Struct.
Das fehlt Dir bei dem MS SizeStruct.
Du kannst schon vom MS Size Struct erben und dann für Height und Width INotifyPropertyChanged implementieren, wenn das reicht..
Es gibt verschiedene mögliche Probleme:* DLL Calling Convention stimmt nicht *Werte müssen auf einen festen Platz gelegt werden *Zusätzliche Referenzen müssen gehalten werden, da der Garbage Collector nicht sieht, was im Unmanaged Bereich abläuft
MSDN Interop Marshalling ist ein guter Startpunkt.
Bei der Build sind wenig reine Linux-User - deswegen macht das das Sql-Server Announcement dort weniger Sinn, finde ich.
Denke mal, dass noch mehr bei Holo Lens kommt.
Wie stellst Du denn die Einfärbung ein - ist da etwas gebunden oder benutzt Du einen Konverter oder etwas anderes?
Bei Akka gibt es als Untermodul Akka Remoting, das die Kommunikation zwischen Client und Server anbietet - dort werden dann auch verschiedene Transports unterstützt.
Wenn Du Mobile Devices mit Polling unterstützst, dann brauchst Du in Akka einen Scheduler, der dann die regelmässigen Nachrichten an die Clients auslöst.
WPF Layout - da wird alles super erklärt.
Sah einen schönen Tweet dazu:
Microsoft hat kein Problem mehr die Produkt-Pipeline geheim zu halten. Es würde eh keiner glauben, was drin ist.
Ich denke, dass hängt mit dem Business Case und der Code Basis zusammen.
Gut möglich, dass der Aufwand gar nicht so groß ist.
Im Vergleich zu Oracle sind SQL Server Lizenzen günstig - da gibt es bestimmt viel Bedarf und damit "Quick Wins".
Und nach .Dot Core ist die Datenbank der nächste logische Schnitt.
MVVM ist der Startblock.
Kern von MVVM ist INotifyChangeProperty, was dann automatisch die Synchronisation zwischen dem GUI Thread und der jeweiligen Datenstruktur vornimmt.
Statt Delegates würde ich Reactive Extensions benutzen. Neben der Entkoppelung von Delegates bekommst Du vor allem die Events als Stream plus Error und Completed und vielen LINQ mässigen Möglichkeiten zum Filtern.
Wenn Du Dir Beispiel anschauen willst, dann würde ich Dir Reactive Trader und Dynamic Trader empfehlen.
Dafür braucht es aber eine ganze Menge Frust-Toleranz, da das zwar sehr gute Beispiele sind, aber die Einstiegshöhe sehr hoch ist.
Mir persönlich gefallen:
http://www.wpf-tutorial.com/ und das Huber Buch.
Ansonsten würde ich mich mehr an einer Beispiel-Applikation versuchen zu orientieren.
Ich fand am Anfang den Simple Music Player als Einstieg gut.
Der Trick bei den generischen Typen in C# ist, daß Generics auf Assembly-Ebene unterstützt werden - d.h. es steht nicht der Quellcode, sondern nur die Metainformation für den JIT-Compiler zur Verfügung. Deswegen muss dem JIT-Compiler geholfen werden.
Ansonsten würde ich Dir Eric Lippert's Blog empfehlen - die Anzahl Artikel zeigt die Komplexität.
Aus meiner Sicht kannst Du sicher dazu eine Arbeit schreiben. Gibt genug Punkte darin, um wissenschaftlich zu arbeiten. Ich habe so etwas ähnliches auch mal bei einem ehemaligen Kunden gesehen, der den Diplomanden dann danach fest eingestellt hat.
Ganz ungefährlich ist die Arbeit nicht, da Du es mit einem klassischen Eisberg-Problem zu tun hast.
Zurzeit gibt es eine Spitze, die herausschaut/bekannt ist, wenn Du dann mehr lernst, wird das Problem viel größer/komplexer. Beim Eisberg sind 90 % versteckt. Das solltest Du von vornherein beachten, insbesondere damit Du die Erwartung Deiner Betreuer steuerst.
Danke....Jetzt klappts auch mit mehreren Windows 😉
Ich brauche das zurzeit im CodeBehind, damit ich im Close Event das Schreiben der UserSettings durchführe. Oder stehe ich irgendwie auf dem Schlauch?
System.Windows.Data Information: 41 : BindingExpression path error: 'UserSettings' property not found for 'object' because data item is null. This could happen because the data provider has not produced any data yet. BindingExpression:Path=UserSettings.Height; DataItem=null; target element is 'MainWindow' (Name=''); target property is 'Height' (type 'Double')
Kannst Du Dein XAML posten?
Ich möchte für meine App mit einer Custom User Settings arbeiten und dort die Einstellungen der Windowsgrößen und -positionen speichern.
Dafür habe ich folgende UserSettings Klasse erstellt:
using System.Configuration;
namespace WindowsSettingsTest
{
public class UserSettingsT : ApplicationSettingsBase
{
[UserScopedSetting()]
[DefaultSettingValue("350")]
public int Height
{
get
{
return (int)this["Hight"];
}
set
{
this["Hight"] = value;
}
}
}
}
Der TestWindow CodeBehind sieht wie folgt aus:
using System;
using System.Windows;
namespace WindowsSettingsTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public UserSettingsT UserSettings { get; set; }
public MainWindow()
{
UserSettings = new UserSettingsT();
InitializeComponent();
}
private void Window_Closed(object sender, EventArgs e)
{
UserSettings.Save();
}
}
}
Das Xaml dazu:
<Window x:Class="WindowsSettingsTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WindowsSettingsTest"
mc:Ignorable="d"
Title="MainWindow" Height="{Binding UserSettings.Height, Mode=TwoWay}" Width="525" Closed="Window_Closed">
<Grid>
</Grid>
</Window>
Was mache ich falsch? Wahrscheinlich ist der Fehler bei Binding im XAML - sehe gerade nix... Danke!
Type: Indicates the message type as follows: Membership Query (0x11), Membership Report (IGMPv1: 0x12, IGMPv2: 0x16, IGMPv3: 0x22), Leave Group (0x17)
Membership Query ist für alle Versionen gleich. Der Report dann unterschiedlich je nach Version und das Leave Group wieder für alle Versionen gleich.
dynamic macht vor allem Sinn, wenn man mit COM Interop z.B Word OLE arbeitet.
Dann muss man nicht mehr alles hin und her casten, so daß der Code für COM Interop einfacher wird.
Es erinnert mich etwas an das Railway Oriented Programming in F#. In F# passt das sehr gut, da das Pattern Matching vollständige Abdeckung aller Fälle erzwingt.
JSON ist ein Standardformat zum Serialisieren. Handlicher und besser lesbar als XML.
Um mal zu Deinem eigentlichen Problem zurückzukommen:
Ich würde die Daten als JSON abspeichern.
Dafür würde ich eine Methode
string ToJson()
und einen Instanzmethode
static SMemory FromJson(string jsonString)
definieren.
Dafür würde ich dann Json.Net nehmen.
Ich würde auch im Regelfall mit Class und nicht mit Struct arbeiten.
Wenn Du VS2015 benutzt - dann solltest Du mal im Output Window nach Binding Fehlern schauen. Du solltest bei "Options" "Debugging" "Output Window" "WPF Trace Settings" schauen, das es angeschaltet ist
Danke für den Link. Hatte auf eine etwas einfachere Lösung gehofft.
Bei WPF bin ich Anfänger 😉
Wie würdet Ihr in WPF für Radio Buttons abbilden, die mit Binding auf enum Werte verweisen sollen.
Mir ist da schon die Struktur nicht klar, deshalb habe ich jetzt keinen Code.
Schau Dich mal bei MathNet.Numerics/ um.
Da gibt es eine NewtonRapson Implementierung. Gibt dort verschiedene Möglichkeiten - auch eine robuste Variante, die Bisektion nimmt, wenn Newton nicht konvergiert.
Das es ein Deadlock im WPF selbst ist, ist ziemlich sicher. Sowohl mit und ohne Debugger nachvollziehbar und ich sehe bestimmte Worker weiterlaufen, ergo hängt der GUI Thread - sogar so, daß nicht mehr Beenden funktioniert und der Task Manager zum Stoppen nötig ist.
In Window1 arbeite ich mit dem Dispatcher - das Race ist zwischen Window1 Click im Grid, der das Grid in Window 2 neu erstellt und Window 1 Update vom Grid. Hatte gehofft, daß der PseudoCode dazu klar war.
Mein Grundproblem ist mehr, daß die ObservableCollection nicht eine Add Methode für eine Enumaration hat und einzelnes Add zu langsam ist.
Ich habe noch eine andere Alternative gefunden:
BindingOperations.EnableCollectionSynchronization(Lines, Locker);
Ich werde mich aber ohnehin mit Euren Vorschlägen beschäftigen.
Da ich schon in anderen Teilen meiner App Rx benutze, werde ich mir auch Dynamic Data anschauen.
Was meinst Du mit Thread-Sichere Auflistung?
Dafür benutze ich zurzeit die ObservableCollection - würdest Du an der Stelle etwas anderes empfehlen?
Muss ich beim Ändern des Verweises der Bindung den Scheduler benutzen oder nicht?
Diesen pauschalen Kommentar kann ich nicht verstehen.
Die Daten sind ja gebunden. Wie soll ich denn sonst den Click auf das Grid abarbeiten? Ich kann es mittels Command machen, aber ich denke nicht, daß das mein Problem löst.
Das Grundproblem ist doch die Synchronisation zwischen einer externen Quelle, die das Grid verändert und Clicks auf das Grid selber.
Der Deadlock ist im WPF selber.
Im Buch von Huber zu WPF steht zum Scheduler drin, dass man Application.Current.Dispatcher.BeginInvoke nehmen soll, um den Deadlock zu vermeiden, aber das reicht nicht aus...
Ich habe im 2. Window auch eine gebundene Observable Collection, wo der Verweis geändert wird. Update: Die habe ich nun auch in den gleichen Scheduler gepackt - leider macht das wohl keinen Unterschied .
Ich habe in meiner WPF App selten Deadlocks und versuche zu verstehen, wie ich das verhindern kann.
In Window 1 habe ich eine ObservableCollection, die durch einen Socket-Thread aktualisiert wird und die als Source für ein DataGrid in dem Window gebunden ist.
Dazu benutze ich zur Zeit folgenden Code.
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(delegate
{
Items.Insert(0, new Item(socketData));
if (Items.Count > maxCount)
Items.RemoveAt(maxCount-1);
}));
Das Deadlock passiert nun, wenn der User auf ein Item im dem Grid einen Click macht, so daß in Window 2 die angezeigten Daten angepasst werden. Da sieht der Code bisher so aus:
private void Grid_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
try
{
var grid = sender as DataGrid;
if (grid.CurrentItem != null)
{
var item = grid.CurrentItem as Item;
if (item.CanFindData())
{
window2.Update(item.Key(), item.Text);
}
}
}
catch (Exception ex)
{
MessageBox.Show("ex:" + ex);
}
}
Was muss ich machen um den Deadlock zu verhindern. Ich hatte mal beide Methoden mit einem lock versehen, aber das hat nicht geholfen. Muss ich das den Click Update im Window2 auch auf dem Dispatcher aufrufen? Da ich schon auf dem GUI Thread bin, dachte ich nicht, daß ich das brauchte.
Für mich sieht das nach einem sicheren Weg in die Hölle aus.
Wenn die Observable Collection gebunden ist, dann musst Du thread-sicher arbeiten. Mir ist neulich ein Deadlock im WPF passiert, als ich gleichzeitig ein GUI Event und ein asynchrones Event auf einer Observable Collection verarbeitet habe.
VerticalAlignment="Bottom" war wohl die Lösung...
<Controls:MetroWindow x:Class="Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Title="Window" Height="Auto" Width="Auto" Closing="Window_Closing">
<Grid Margin="0,0,0,116">
<DataGrid HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" Name="TradingGrid" FontSize="18" FontStyle="Normal" FontWeight="Bold" Height="Auto" CanUserResizeColumns="True" MouseDoubleClick="TestGrid_MouseDoubleClick" IsReadOnly="True" CanUserReorderColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" CanUserSortColumns="False" AutoGenerateColumns="False" Width="Auto">
</DataGrid>
<Button DockPanel.Dock="Bottom" x:Name="1" Content="1" HorizontalAlignment="Left" Margin="0,454,0,-90" VerticalAlignment="Stretch" Width="75" />
<Button DockPanel.Dock="Bottom" x:Name="2" Content="2" HorizontalAlignment="Left" Margin="0,454,0,-90" VerticalAlignment="Stretch" Width="75" />
</Grid>
</Controls:MetroWindow>
Wie schaffe ich, dass die Buttons immer direkt unter dem DataGrid sind? Habe ohne Erfolg mit Grid.Rows und DockPanel probiert und stecke jetzt fest.
Wenn Dir Material Design zusagt, dann würde ich das hier mal ausprobieren. Da gibt es zumindest moderne Controls als Open Source.
Ich benutze gerne PropertyChanged.Fody, damit ich nicht manuell INotifyPropertyChanged implementieren muss.
Dann wird für jedes Public Property mit getter und setter INotifyPropertyChanged direkt beim Compilieren generiert.
Ich würde an Deiner Stelle Deine Updates nur alle x ms im Block verarbeiten.
Eine Möglichkeit wäre es, eine Blocking Collection zu benutzen.
DataReceived schreibt in die Blocking Collection und ein eigener Update-Thread fast alle Änderungen in einem Schritt zusammen und ruft dann einmal für x ms das Invoke auf.
OpenXML ist nicht unbedingt schwerer als Interop, es ist nur eine komplett andere Sichtweise.
Bei Interop automatisierst Du Aktionen in der GUI, bei OpenXML musst Du mehr auf Basis des Dokuments denken.
Andre Krämer hat einen ganz ordentlichen Vortrag mit Beispiel-Code dazu - das ist für Word.
Bei einer Anpassung würde ich auf jeden Fall auf Office Open XML umstellen - Interop ist nicht 100% stabil und auf Windows Server oder Azure nicht unterstützt - außerdem kannst Du dann bei den SW-Lizenzen sparen.
Was benutzt Du zur Synchronisation? lock, Interlocked oder etwas anderes?
Deine Beschreibung legt nahe, daß Du das entweder gar nicht oder falsch machst.
Volatile Almost useless for multithread programming und atomicity, volatility and immutability are different
geben Dir mehr Anregungen.
Meine Erfahrungen mit Interlocked sind nicht so positiv - im Vergleich zu lock war es eher langsam...
Die entscheidende Frage hast Du Dir auch gestellt - das GUI wird immer in einem einzigen Thread aktualisiert - daher brauch man immer Control.Invoke/Dispatcher.Invoke zum Aktualisieren...
Bei WPF solltest Du mit MVVM/DataBinding arbeiten.
Dazu würdest Du das Grid auf eine Observable Collection binden.
Damit Du nicht IProperityNotifyChange auf jedes Property manuell erstellen musst, würde ich mir Fody/PropertyChanged anschauen, um Dir viel getippe zu sparen.
Ich benutze als Einzelentwickler Mercurial via TortoiseHG und Visual HG.
Wichtig ist bei Euch neben dem Tool, dass Ihr Euren Entwicklungs-Prozess etwas mehr vereinheitlicht.
Wahrscheinlich geht es da um Managed DLLs/Exes.
Du kannst mit normalen .NET Unit-Tests nur die Interop-Schicht testen.