Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von sth_Weird
Thema: Problem beim Zugriff auf generische Klasse, die in Interface gepackt ist...
Am im Forum: Rund um die Programmierung

Ja ich hatte auch schon befürchtet, dass ich um Reflection nicht rumkomme.

Gruß & Danke
sth_Weird

Thema: Problem beim Zugriff auf generische Klasse, die in Interface gepackt ist...
Am im Forum: Rund um die Programmierung

Hallo,
ich habe ein Problem beim Zugriff auf eine generische Klasse, die ein Interface implementiert...
Ich bekomme von einer externen Quelle (auf die ich keinen Einfluss habe) ein Objekt vom Typ IMessage übergeben. Dieses enthält im konkreten Fall eine generische Implementierung von IMessage -> GenericMessage<T>. GenericMessage<T> enthält ein Property DataItem vom Typ T. Der Typ von T interessiert mich an dieser Stelle nicht, ich möchte einfach das, was in DataItem steht, in einer lokalen Variablen (vom Typ object) speichern und später weiterverarbeiten (sagen wir der Einfachheit halber mal, ich möchte das Objekt mit ToString in der Console ausgeben (angenommen ToString von T liefere informative Daten).
Aber wie komme ich an diese Information ran? Ich weiß, dass das Objekt, das mir als IMessage übergeben wird, vom Typ GenericMessage<T> ist, kenne aber den Typ von T nicht und möchte auch nicht alle möglichen bekannten Typen von T durchprobieren, ich möchte einfach nur an das DataItem Property kommen und das in einer lokalen Variablen vom Typ object speichern...

Gruß & Danke
sth_Weird

Thema: [gelöst] ExpressionTrees/ExpressionVisitor: Wie lokale Variable "als Zahl" in Tree behandeln
Am im Forum: Rund um die Programmierung

Hmm, dann komme ich wohl nicht um das compilen drum rum...
Danke für die Antwort!

gruß
sth_Weird

Thema: [gelöst] ExpressionTrees/ExpressionVisitor: Wie lokale Variable "als Zahl" in Tree behandeln
Am im Forum: Rund um die Programmierung

hallo,
Ich würde gerne eine Expression<Func<T,Res>> in String-Form ausgeben.
Dafür habe ich einen ExpressionVisitor implememtiert (von der abstrakten Basisklasse abgeleitet).
Soweit so gut, nur die Parameter werden nicht so angezeigt, wie ich das gerne hätte.
Eine einfache Expression sieht z.B. so aus:


p => p.Age ≥ myLocalIntVariable
myLocalIntVariable ist eine lokale int-Variable in einer Funktion (der Wert wird aus der GUI ausgelesen).
Im ExpressionTree ist myLocalIntVariable eine ConstantExpression. Ich möchte hier den Wert ausgeben, der dort gespeichert ist. Leider steht im .Value Property der ConstantExpression was "kryptisches" drin, und nicht der einfache Zahlenwert, den ich haben möchte. Ich habe nun soviel über ConstantExpressions gelesen, dass ich weiß, dass da ein Zwischenspeicher für den Wert erzeugt wird, in dem Value als object gespeichert wird. Wenn ich beim Debuggen die ConstantExpression im QuickWatch angucke, kann ich das Value Property aufklappen und sehe dann den tatsächlichen Zahlenwert, der drin steht. Aber über den Code scheine ich da so nicht ran zu kommen.
Ich habe Beispielcode gefunden, wie ich einen ExpressionTree selbst aufbaue, und so mit bestimmten Tricks erreichen kann, dass meine lokale Variable wirklich als Wert in den ExpressionTree reinwandert (also so als hätte ich geschrieben p => p.Age ≥ 5 oder so). Das ist natürlich wesentlich komplizierter als die Syntax oben. Daher frage ich mich, ob ich man nicht mit einfacheren Mitteln zum gleichen Ziel kommt... Ich habe nämlich zum Teil verschachtelte Prüfungen, wie p => p.x.y.z > a.b.c, und denke den Tree da händisch aufzubauen wird doch ganz schön komplex...
Auch über alternative, einfache Wege zum Ziel wäre ich dankbar.
(ich habe schonmal gelesen dass man durch compilen der Expression weiter kommen könnte, aber das sei sehr langsam, und da ich die Expression auf viele Datensätze loslassen will :/ ...)

gruß & danke
sth_Weird

Thema: Liste mit Expression<Func<T, bool>> für unterschiedliche Ts...? [gelöst]
Am im Forum: Grundlagen von C#

List<LambdaExpression> funktioniert, danke!

Thema: Liste mit Expression<Func<T, bool>> für unterschiedliche Ts...? [gelöst]
Am im Forum: Grundlagen von C#

Hi,
ich habe mir eine GUI zum Anlegen von Filtern geschrieben. Jeder Filter ist definiert als Expression<Func<T, bool>>.
Nun möchte ich alle Filter in einer Liste speichern. Der Haken dabei: das T ist nicht bei allen Filtern der gleiche Datentyp, es kann also einmal Expression<Func<string, bool>> sein, ein anderes Mal Expression<Func<MyDataType, bool>>. Zusatzinfo: Nicht alle Filter sind für ein und dasselbe Ziel gedacht, daher sind die unterschiedlichen Datentypen kein Widerspruch.
Nun dachte ich mir, das einfachste ist, ich verwende als Datentyp object, da das ja die Oberklasse von allem ist.

List<Expression<Func<object, bool>>> myList;
...
Wenn ich nun aber Daten einfügen will:


Expression<Func<MyDataType, bool>> myExpression = ...;
// das geht nicht
myList.Add(myExpression);
// das geht auch nicht:
myList.Add((Expression<Func<object, bool>>)myExpression)

dann meckert der Compiler, er könne Expression<Func<MyDataType,bool>> nicht umwandeln in Expression<Func<object, bool>>.

A) Warum kommt hier diese Fehlermeldung, wo object doch die "Überklasse" ist. In eine List<object> kann ich ja auch alles adden.

B) Wie muss ich die Liste definieren bzw. wie meine Expression einfügen, damit es geht, oder ist die einzige Alternative (wenn ich mir keine eigene Listenklasse anlegen will...), die ganze Expression-Liste als List<object> anzulegen?

gruß & danke
sth_Weird

Thema: Prioritäten von Styles und "explizit" angegebenen Properties?
Am im Forum: GUI: WPF und XAML

Das hatte ich garnicht mehr ausprobiert, da ich gleich die Meldung gesehen hatte. Habe es nochmal zurückgebaut und ja, die TextBox war trotzdem gesperrt...

Ich hätte erwartet, dass hier optimiert wird...also erst mal "im Background" alles ausgewertet wird, und dann für das jeweilige Property nur das angewandt wird, "was am Ende da steht". Aber deine Erklärung mit dem roten/blauen Auto leuchtet schon ein...

Gruß
sth_Weird

Thema: Prioritäten von Styles und "explizit" angegebenen Properties?
Am im Forum: GUI: WPF und XAML

Ich habe noch etwas rumprobiert und folgendes herausgefunden:
- ich habe ein benanntes Style erstellt für meine Textbox, die ReadOnly sein soll. Das einzige, was dieses Style macht ist, dass es ReadOnly immer auf True setzt.
- wenn ich der besagten TextBox im ItemTemplate dieses Style zuweise, dann funktioniert es, die Meldungen mit dem fehlenden Property sind weg und die TextBox ist immer ReadOnly, wie gewünscht :)
Weshalb es nicht funktioniert, wenn man nur das ReadOnly überschreibt, wüsste ich trotzdem gerne noch...

gruß
sth_Weird

Thema: Prioritäten von Styles und "explizit" angegebenen Properties?
Am im Forum: GUI: WPF und XAML

Hallo,
ich habe ein Problem mit einem View.
Ich habe in den Resources ein Style für TextBoxen angelegt. Dieses Style setzt, abhängig von einem Wert im ViewModel des Views, alle TextBoxen auf ReadOnly oder Schreibbar. Zur Veranschaulichung nehmen wir mal an das ViewModel hieße "MainViewModel" und das Property "WriteProtection"
Der View enthält auch ein ItemsControl. Das ItemsControl zeigt eine Liste mit ViewModels "ElementViewModel" an (die Liste der ElementViewModels ist im MainViewModel als Property enthalten).
Das ItemTemplate enthält nun wiederum auch eine TextBox. Diese TextBox will ich immer ReadOnly haben. Daher habe ich explizit für diese TextBox im XAML das Property IsReadOnly=True definiert.
Nun meckert VS für die TextBox im ItemsControl immer, "ElementViewModel" hätte kein "WriteProtection" Propery, welches vom Property "IsReadOnly" der TextBox verlangt würde.
(nur zur Klarstellung: Dass mein angezeigtes Objekt im ItemsControl einen anderen DataContext (= aktuell angezeigtes ElementViewModel) hat und damit das WriteProtection des MainViewModels nicht kennt ist mir klar, also da liegt nicht das Verständnisproblem...)
Ich verstehe die Fehlermeldung nicht, da ich bei IsReadOnly explizit True angegeben habe. Dieser Wert, der explizit für das Control angegeben ist, müsste doch eigentlich den Wert aus dem Style, der in den Resourcen angegeben ist, überschreiben, oder???
Mein Kenntnisstand war, dass explizit angegebene Werte höherprior sind als die Werte die in den Resourcen des eigenen View/UserControl stehen, und diese wiederum höherprior als die Resourcen, die in anderen, verwiesenen Resourcen stehen.

Wo ist mein Denkfehler, warum wird fürs ItemsControl-Template scheinbar das "IsReadOnly" aus dem Style verwendet und nicht mein explizit angegebener Wert?

In den Resources des Views (relevanter Ausschnitt):


<Style TargetType="TextBox">
                <Setter Property="IsReadOnly" Value="{Binding Path=WriteProtection, ... /Setter>

ItemsControl im View (nur die relevanten Ausschnitte):

 <ItemsControl x:Name="ICtrlElements"... ItemsSource="{Binding Path=MyElements}" >
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="0,0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="120" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <TextBox Grid.Column="1" Text="{Binding ExampleProperty, Mode=OneTime}" IsReadOnly="True" TextWrapping="Wrap" />

Der Fehler:
Fehler
System.Windows.Data Error: 40 : BindingExpression path error: 'WriteProtection' property not found on 'object' ''ElementViewModel' (HashCode=49829907)'. BindingExpression:Path=WriteProtection; DataItem='ElementViewModel' (HashCode=49829907); target element is 'TextBox' (Name=''); target property is 'IsReadOnly' (type 'Boolean')

gruß & danke
sth_Weird

Thema: Wie testet man ViewModels die in Views mit AttachedBehaviours (Eingabeformat) verwendet werden?
Am im Forum: GUI: WPF und XAML

Zitat
Besagtes NumericTextBoxBehaviour halte ich für einen furchtbaren Anwendungsfall für AttachedBehaviours, denn WPF stellt genau für diesen Zweck eben schon Eingabevalidierungen zur Verfügung. Aber das ist meine persönliche Meinung.

Also dieses NumericTextBoxBehaviour verwende ich, damit ich direkt Int-Properties im View anbinden kann. Gebe ich sonst einen String in eine TextBox ein, die mit einem Int-Property verbunden ist, dann fliegt ne Exception.
Als Work-Around im Netz steht, man könnte an ein String-Property binden und nur wenn die Eingabe gültig ist, den Wert auf das tatsächliche Int-Property schreiben. Da empfinde ich dann aber ein Behaviour (oder auch eine ValdiationRule) als elegantere Lösung...
Jetzt nach deinem Kommentar frage ich mich, von welchen (anderen?) Eingabevalidierungen du sprichst, die WPF schon zur Verfügung stellt (und ich evtl noch nicht kenne)???
Mir fiele zum Thema Eingabevalidierung nur noch das IDataError-Interface ein, welches ich auch bei mir implementiert habe für weiterführende Validierungen. Aber dieses kommt erst später zum Zug und fängt falsche Eingaben in meine (an ein Int-Property gebundene) TextBox nicht ab...

Aber danke schon mal für deine Rückmeldung zum Thema Testen. So hatte ich mir das auch gedacht - also dass man jede Komponente einzeln testet, ob sie das macht was sie soll, und sich dann darauf verlässt, dass sie im Einsatz in einem größeren System das richtige macht. Sonst wären größere Systeme wahrscheinlich auch garnicht testbar...

gruß
sth_Weird

Thema: Wie testet man ViewModels die in Views mit AttachedBehaviours (Eingabeformat) verwendet werden?
Am im Forum: GUI: WPF und XAML

Das mit dem Int ist aber ein sehr einfacher Fall...
Um mal etwas komplexeres zu nehmen, ich könnte ein AttachedBehaviour haben, das nur IP-Adressen oder GUIDs als Eingabe zulässt (angenommen das ViewModel würde diese als String anbieten).
Es ist eine komfortable Vorstellung, dass ich nur meinen Textboxen in den Views das AttachedBehaviour zuweisen muss und es werden nur gültige Eingaben erlaubt. In den ViewModels muss ich nichts weiter machen (es sei denn ich muss noch Dinge prüfen, die für dieses ViewModel spezifisch sind).

Es gibt neben AttachedBehaviours z.B. auch ValidationRules, welche man direkt im XAML verwenden kann und welche Eingaben prüfen können...das Problem müsste hier dasselbe sein - ich bekomme die Fehler nicht in mein ViewModel! Mir scheint manchmal, dass sich diese Mechanismen und das MVVM-Prinzip hier in die Quere kommen :/

Gruß
sth_Weird

Thema: Wie testet man ViewModels die in Views mit AttachedBehaviours (Eingabeformat) verwendet werden?
Am im Forum: GUI: WPF und XAML

Hallo,

ich habe eine Anwendung mit MVVM-Pattern. Viele Eingaben in meinem View erfordern ein bestimmtes Format, z.B. nur Zahlenwerte, Texte die nur eine bstimmte Länge haben dürfen, Texte die nur in Großbuchstaben sein dürfen, Texte ohne Leer/Sonderzeichen etc.
Ich liebäugle hier mit einem AttachedBehaviour zur Eingabeprüfung, im Internet habe ich auch schon Beispiele gefunden (z.B. NumericTextBoxBehaviour), die ich gut auf meine Anforderungen anpassen könnte.
Ich frage mich nun aber, wie man so etwas testet. Teste ich nur das ViewModel, würde dieses ja Werte annehmen, die nicht gültig sind, da in der realen Umgebung der View die Werte durch das AttachedBehaviour abweisen würde. Andererseits, wenn ich die Prüfung im ViewModel nochmal implementiere, wozu dann überhaupt noch das AttachedBehaviour (die Prüfungen wären ja doppelt implementiert und das ganze damit sogar noch fehleranfällig).
Oder testet man in dem Fall das AttachedBehaviour einzeln und wenn das passt, dann testet man das ViewModel nur noch mit "guten" Eingaben, da man weiß, dass gar keine schlechten durchkommen?
Oder testet man beide in Kombination, d.h. man arbeitet im UnitTest mit ViewModel UND AttachedBehaviour und schickt einen neuen Wert erst an eine (evtl. statische) Prüffunktion im AttachedBehaviour, bevor man ihn an das ViewModel übergibt?

Gruß
sth_Weird

Thema: Eine Listview verschiedene ViewModel WPF<-> MVVM
Am im Forum: GUI: WPF und XAML

Einfacher als mit TemplateSelector gehts wenn man (Default-)DataTemplates für die ViewModels erstellt. Dann wird die Ansicht in der ListView automatisch je nach VM-Type angepasst (auch wenn neue dazukommen muss man nichts weiter machen als ein neues DataTemplate dafür anzulegen).
Mit dem TemplateSelector kann man komplexere Sachen realisieren, da ist man maximal flexiblel, in den meisten (einfachen) Fällen braucht man ihn aber nicht.

gruß
sth_Weird

Thema: Navigieren zwischen Usercontrols anhand eines dynamisch erstellten TreeViews
Am im Forum: GUI: WPF und XAML

Ich würde auf keinen Fall den VM Namen in der Datenbank speichern, sondern dafür eine Enumeration erstellen. Damit kannst du sicherstellen, dass nur erlaubte Werte eingetragen werden und bist auch vor Namensänderungen sicher! In der Datenbank steht nur die "ID" bzw. der Enumerationswert, diesen kannst du im C# Code auswerten und das entsprechende ViewModel erstellen.
Die ganze if/else Geschichte kannst du noch umgehen, wenn du dir im Code ein Dictionary hältst, welches die Enumerationswerte mit dem Ziel-ViewModel verknüpft (key = Enumeration, value = ViewModel-Type). Dann kannst du für jeden Eintrag der Datenbank nachschlagen welches ViewModel gebraucht wird und dieses ViewModel dynamisch instanziieren. Kommen neue Enumerationswerte (= ViewModels) dazu, musst du nur noch das Dictionary erweitern, die Verwendungsstelle bleibt gleich.
Ansonsten aber sehe ich an deiner Herangehensweise nichts falsches. Es gibt sicher auch andere Wege, aber da müsste man das Gesamtsystem kennen..

gruß
sth_Weird

Thema: ComboBox mit Bildpfaden und Image-DataTemplate...wie "kein Bild" darstellen???
Am im Forum: GUI: WPF und XAML

Hallo,

also bei mir fliegt eine Exception, dass der String nicht als ImageSource verwendet werden kann...diese Exception fliegt auch nur wenn mein Binding null liefert.

Ich habe es jetzt mit einem leeren Image gelöst und damit ich dessen Pfad nicht sehe, einen Trigger an den Pfad-TextBlock im DataTemplate gehängt, der diesen ausblendet wenn der Pfad des leeren Images drinsteht.

gruß
sth_Weird

Thema: ComboBox mit Bildpfaden und Image-DataTemplate...wie "kein Bild" darstellen???
Am im Forum: GUI: WPF und XAML

Hallo,

ich habe in meinem View eine ComboBox zur Auswahl eines Bildes. Mein ViewModel liefert eine Liste mit Bildpfaden. Außerdem habe ich noch ein SelectedImage String im ViewModel. Ein DataTemplate erledigt, dass in der ComboBox die Daten als Image und Bildpfad darstellt werden. Soweit so gut.
Außer einem Bild soll es auch noch möglich sein, nichts (also kein Bild) auszuwählen. Hieran scheitere ich bisher. Ich habe meine String-Liste mit den Bildpfaden um einen Eintrag "null" erweitert. Nun wirft die Anwendung, wenn ein Objekt auf kein Bild verweist, natürlich eine Exception, dass das kein gülteriger Bildpfad ist, der als ImageSource verwendet werden kann.
Mein nächster Gedanke/Ansatz war, zwei unterschiedliche DataTemplates zu halten, eines für den Fall dass ein Bildpfad gegeben ist, eins für den "null"-Fall.
Nun kann ich nach dem Starten der Anwendung Objekte anzeigen, die kein Image haben, das funktioniert (es wird das richtige Template ohne Image ausgewählt). Kommt dann ein Objekt mit Image, wird das korrekte DataTemplate mit Image verwendet. Aaaber kommt als nächstes wieder ein Objekt ohne Image, fliegt wieder die altbekannte Exception, dass die ImageSource umgültig sei. Obwohl doch das andere Template ohne Image verwendet werden sollte!?
D.h. irgendwie versucht er wohl noch mit dem alten (Image-)Template zu binden, bevor das korrekte DataTemplate zum Zug kommt... Hier meine ComboBox-XAML:

<ComboBox Grid.Row="7" Grid.Column="1" Name="CboIconPath" ItemsSource="{Binding Path=Icons}" SelectedItem="{Binding Path=SelectedIcon, Mode=TwoWay, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Margin="10,2,5,2" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="400" >
                <ComboBox.Resources>
                    <DataTemplate x:Key="IconNameAndPic">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="{Binding}" MinWidth="100" MinHeight="20"/>
                            <TextBlock Text="{Binding}" VerticalAlignment="Center" />
                        </StackPanel>
                    </DataTemplate>
                    <DataTemplate x:Key="IconNameOnly">
                        <TextBlock Text="{Binding}" VerticalAlignment="Center" />
                    </DataTemplate>
                </ComboBox.Resources>
                <ComboBox.Style>
                    <Style TargetType="ComboBox">
                        <Style.Setters>
                            <Setter Property="ItemTemplate" Value="{StaticResource IconNameAndPic}"></Setter>
                        </Style.Setters>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding}" Value="{x:Null}">
                                <Setter Property="ItemTemplate" Value="{StaticResource IconNameOnly}"></Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                    </ComboBox.Style>
                </ComboBox>

Hat jemand eine Idee wo das Problem liegt? Vielleicht daran, dass mein "Default-Template" (im Setter, ohne Trigger) das Template mit Bild ist und das Template ohne Bild im Trigger gesetzt wird (leider gibt es kein "Nicht Null" sonst könnte ich das ausprobieren)??? Wäre es ein Unterschied, anstelle im XAML mit Triggern zu arbeiten, einen TemplateSelector zu verwenden?
Ich hätte noch eine alternative Idee, statt "null" eine Art "EmtptyImage" Image zu erstellen, dann hätte man immer ein Bild...wenn es irgendwie mit "null" funktionieren würde wäre das aber natürlich weniger Aufwand...

gruß & danke
sth_Weird

Thema: MenuItem, das in zwei ContextMenus verwendet wird, "verschwindet"
Am im Forum: GUI: WPF und XAML

Eine Instanz eines Controls kann es immer nur an einer Stelle geben. Es hat nur einen Parent. Fügt man es an einer anderen Stelle hinzu, dann ändert sich der Parent und es ist an der alten Stelle logischerweise nicht mehr da.
Mit der Shared=false Eigenschaft erzwingst du, dass an jeder Stelle quasi eine eigene Instanz des Controls erzeugt wird. Deshalb funktioniert es dann mit mehreren Verwendungsstellen.
Die Lösung von ErfinderDesRades ist trotzdem sauberer, vorausgesetzt du hast Zeit und Muse um das umzusetzen.
Für einfache, private Anwendungen geht die Lösung mit dem Shared aber auch, man sollte sich halt im Kopf behalten, dass es eher Quick & dirty Praktik ist...

gruß
sth_Weird

Thema: Ausgabe in TextBox als Hex-Wert
Am im Forum: GUI: WPF und XAML

Ich krame das Thema noch mal raus da es dazu passt.
Mit dem oben erwähnten StringFormat klappt das alles bei mir so lange gut, bis der Anwender den kompletten Text der Textbox löscht oder eine inkompatible Eingabe macht. Dann fliegt eine FormatException, die Eingabezeichenfolge habe das falsche Format. Die Exception fliegt (logischerweise), bevor der Setter des Bindings aufgerufen wurde, ein Breakpoint im Setter des gebundenen Properties wird nicht angesprungen (wenn die Exception fliegt, steht die Anwendung in einer while(continueLoop)-Schleife in der Microsoft-Application.cs).
Gibt es eine Möglichkeit, diese Exception zu behandlen, oder muss man an dieser Stelle auf die Formatierung im XAML verzichten und es im Code lösen (z.B. mit einem Konverter).

gruß & danke
sth_Weird

Thema: ListBox DataTempalte für Items mit ComboBox funktioniert nicht richtig
Am im Forum: GUI: WPF und XAML

da ich nicht weiß, ob ich deine Interpretation richtig verstanden habe, hier vielleicht noch mal anders:
Datenbanktechnisch habe ich eine Tabelle Customers und eine Tabelle Products (n:m Beziehung).
Mein ViewModel bildet einen Customer ab. In der ListBox möchte ich nun quasi die Verbinding herstellen zischen diesem Customer und der Products Tabelle, allerdings kann ein Product mehrfach verknüpft werden. Aber in seinen Eigenschaften nicht verändert, d.h. das Product-Objekt muss immer gleich bleiben!
D.h. für mein Programm, in der ComboBox stelle ich alle Products zur Verfügung die in der Products Tabelle stehen, ich wähle davon eines aus und genau dieses Product muss dann in die Products-ObservableCollection rein, die an die ListBox gebunden ist. Ändere ich die Auswahl in der ComboBox, dann muss in der ObservableCollection eigentlich genau dieses Objekt ausgetauscht werden.
Und genau hier hänge ich, also dass meine Änderungen an der ComboBox nicht in die ObservableCollection übergehen...
Ich habe auch ein Command, das einen neuen Eintrag (erst mal null) in der ObservableCollection erstellt. Dieser wird dann auch gleich als neues Item mit ComboBox (ohne Auswahl) in meiner ListBox angezeigt. Aber wenn ich dann was in der ComboBox auswähle, dann wandert diese Auswahl nicht in die ObservableCollection zurück, dort bleibt das vorher eingefügte null stehen...aber auch wenn ich statt null ein (existierendes) Dummy-Product in die ObservableCollection eintrage und im View ein anderes Product in der Combo auswähle, ich bekomme im ViewModel rein garnichts davon mit, die ObservableCollection wirf keine Events (ich hätte hier ein Replace erwartet).
Warum weiß ich nicht, und ich finde auch beim googlen keine Lösung, obwohl ich denke, dass das was ich suche doch ein gängiges Anwengsszenario sein sollte.
Wie mir da ein ViewModel helfen kann, das verstehe ich nicht. "." sollte doch schon der DataContext des ListBoxItems sein, oder?
Das mit dem Delete-Button wird recht trivial, wenn der Rest mal geht.

gruß
sth_Weird

Thema: ListBox DataTempalte für Items mit ComboBox funktioniert nicht richtig
Am im Forum: GUI: WPF und XAML

Hallo,
ich habe in meinem Customer-ViewModel eine ObservableCollection<Product> Products. Außerdem gibt es noch eine Liste List<Product> AllProducts die alle Produkte liefert (hieraus kann sich der Customer quasi seine Products auswählen).
Die Producs Liste binde ich im View an eine ListBox. Die einzelnen ListBoxItems möchte ich als ComboBoxen anzeigen (hierfür habe ich ein DataTemplate definiert), ItemsSource der ComboBox soll immer AllProducts sein, SelectedItem dann halt der aktuelle Eintrag des ListBoxItems (also das Element aus Products das zu dem ListBoxItem gehört).
Leider bekomme ich das nicht zum Laufen...Ich bekomme es soweit hin, dass ich eine ComboBox sehe und diese AllItems anzeigt. Aber wie bekomme ich es jetzt hin, dass der ListBoxItem auch der SelectedItem der ComboBox ist, und noch wichtiger, wenn ich in der ComboBox einen anderen Eintrag auswähle, soll dieser sich ja auch in der ObservableCollection niederspiegeln. Das tut es zur Zeit nicht (ich habe mich an die CollectionChanged der ObservableCollection angehängt, dort fliegt kein Event, wenn ich einen anderen Eintrag in der ComboBox auswähle :( )
Hier ein Teil meiner XAML, hier habe ich versucht SelectedItems auf . zu setzen. da das ja das aktuelle Binding ist oder???


<ListBox Name="LbProducts" ItemsSource="{Binding Path=Products}" Margin="10,2,5,2" HorizontalAlignment="Left" VerticalAlignment="Center" Width="400">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid Margin="0,2">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="50" />
                                </Grid.ColumnDefinitions>
                                <ComboBox Name="CboAllProducts"  Grid.Column="0" ItemsSource="{Binding Path=DataContext.AllProducts, ElementName=LbProducts}" SelectedItem="{Binding Path=., Mode=TwoWay}" />
                                ..hier soll noch ein Button zum Löschen hin                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
hier ein Teil des Products-Properties


public ObservableCollection<Product> Products
    {
      get
      {
        if (this.products == null)
        {
          this.products= new ObservableCollection<Products>(myModel.Products);
          this.products.CollectionChanged +=
            delegate(object sender, NotifyCollectionChangedEventArgs e)
            {
              switch (e.Action)
              {
                 // hier ist Code drin, der bei Aendungen der ObservableCollection das Model anpassen soll...wie geschrieben der Debugger springt hier nie rein, wenn ich in der Combo ein anderes Element auswähle...
Die AllProducts Liste wird vom Konstruktur erzeugt und bleibt immer gleich.

Kann mir jemand sagen, wo der Fehler liegt???

grüße & danke
sth_Weird

Thema: Reaktionszeit für Combobox-Eingaben anpassen
Am im Forum: GUI: WPF und XAML

Schade, dass da nichts zu machen ist..
Nuja, aber zu wissen dass etwas nicht (zumindst nicht so einfach) geht, das bringt einem auch schon mal etwas weiter ;)

Ich hätte noch die Idee, mich von ComboBox abzuleiten, mich dort an die KeyPresses zu hängen und die Zeit mit Timer zu überwachen...aber kann ich in der Ableitung überhaupt die eingebaute Filter-Funktion manipulieren/überschreiben?
Oder ich bau mir ne eigene ComboBox aus Textbox, "v"-Button und Popup...aber das wäre auch suboptimal.

gruß & danke

Thema: Reaktionszeit für Combobox-Eingaben anpassen
Am im Forum: GUI: WPF und XAML

Hallo,

ich verwende in meinem Formular eine WPF ComboBox, die Items und das SelectedItem sind an Properties des ViewModels gebunden.
Wenn ein User die ComboBox öffnet und Buchstaben eintippt, dann springt die ComboBox automatisch zum nächsten Eintrag, der mit den eingetippten Buchstaben beginnt. Wird für eine "längere" Zeit nichts getippt und der User fängt erneut zu tippen an, dann nimmt die ComboBox an, es fängt ein neues Suchwort an. Das ist das Standard-Verhalten der WPF ComboBox, das man hat, ohne eine Zeile Code programmieren zu müssen.

Diese Zeitspanne, die maximal zwischen dem Tippen zweier zusammengehöriger Buchstaben vergehen darf, ist manchen Usern leider zu kurz (quasi für User, die mit der Tastatur noch nicht so gut vertraut sind und einzelne Buchstaben suchen müssen). Ist es möglich, die Zeitspanne zu vergrößern?

Wenn jemand einen treffenderen Titel findet, darf ihn gerne anpassen, mir ist nichts aussagekräftigeres eingefallen, ohne die maximale Anzahl der Buchstaben zu überschreiten.

Gruß & Danke
sth_Weird

Thema: WPF: DataTrigger bei Checkboxen reagiert nicht
Am im Forum: GUI: WPF und XAML

Nuja das ganze hat eigentlich in dem Sinne kein ViewModel, es ist ein CustomControl das ein DependencyProperty "MyFlags" hat. Ich verwende es in einem Formular, und binde dort das MyFlags DependencyProperty an das ViewModel des ganzen Formulars. Ich hätte die Logik nun ungern im ViewModel des Formulars untergebracht, da sie ja an jeder Verwendungsstelle des CustomControls gilt.
Als einzig andere Alternative fällt mir dann aber ein, in meinem CustomControl noch ein DependencyProperty einzufügen das ich an die ungebundene Checkbox hefte. Leider wäre dieses Property dann auch nach außen sichtbar an allen Verwendungsstellen und könnte gebunden werden. Das würde mir nicht so gut gefallen...Oder gibt es DependencyProperties, dich im im DataTemplate des CustomControls binden kann, aber nicht an der Verwendungsstelle?
Oder doch mit Events arbeiten??? Es ist ja ein abgeschlossenes CustomControl da dürfte das ja eigentlich MVVM-technisch nicht so tragisch sein...

gruß
sth_Weird

Thema: WPF: DataTrigger bei Checkboxen reagiert nicht
Am im Forum: GUI: WPF und XAML

hallo,

ja, aber ich möchte ja das IsChecked auf true setzen (was dann den Wert des Properties im hinterlegten Binding aktualisieren soll)...
Also ganz einfaches Beispiel: ich habe 2 Checkboxen die gebunden sind an 2 boolsche Werte des ViewModels. Eine dritte ungebundene Checkbox soll, wenn IsChecked = true wird, diese beiden Checkboxen auch IsChecked = true setzen. So ne Art "alles anwählen".
Da die Checkboxen bzw. IsChecked aber gebunden ist scheint das nicht zu gehen. Nimmt man das IsChecked-Binding raus tut's, aber wie soll der Wert dann zurück ins ViewModel wandern, wenn er nicht gebunden ist?.

Als Gegenbeispiel der umgekehrte Fall, wenn beide gebundene Checkboxen IsChecked=true sind, sollte die "alles anwählen" Checkbox automatisch auch angewählt sein.
Das bekommt man über einen DataTrigger prima hin, denn die Ziel-Checkbox ist ja nicht gebunden und somit kann man deren IsChecked im Setter des DataTriggers überschreiben.

gruß
sth_Weird

Thema: WPF: DataTrigger bei Checkboxen reagiert nicht
Am im Forum: GUI: WPF und XAML

Ok das war's, danke...Das IsChecked = false sollte der Defaultwert sein.

Ich habe jetzt auch noch einen anderen Fall, da ist IsChecked gebunden (und hat Converter und ConverterParameter).
Aus eurer Begründung der Antworten leite ich dann aber ab, dass ich den Wert von IsChecked hier auch nicht so wie von mir angedacht über einen Trigger ändern kann, oder??? Wie müsste ich dann vorgehen, wenn ich das IsChecked setzen will, aber das Binding beibehalten (der Trigger soll quasi das gleiche auslösen, als hätte ich manuell auf die CheckBox geklickt, d.h. der Wert der gebundenen Property soll sich somit auch aktualisieren)? Wie gesagt das Binding von IsChecked bindet ein Property des ViewModels, hat Converter und ConverterParameter.
Direkt im Setter das gebundene Property setzen geht ja auch nicht:

<Setter Property="{Binding Path=MyFlags, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource FlagsToBoolConverter}, ConverterParameter=FlagXYZ}" Value="False"></Setter>
wirft zur Laufzeit ne Exception.
Mir fallen als Lösung nur ein, jedes einzelne Flag als DependencyProperty meines CustomControls zu implementieren und im setzen/rücksetzen die Sonderaktionen durchzuführen, die ich eigentlich mit den DataTriggern abhändeln wollte. Damit ist allerdings die Idee futsch, dass mein CustomControl nur die Gesamtmenge der Flags als DependencyProperty anbietet und nicht jedes einzelne.
Oder ich machs mit Events, ist aber sehr böse nach MVVM und auch nicht testbar...

Gruß & danke
sth_Weird

Thema: WPF: DataTrigger bei Checkboxen reagiert nicht
Am im Forum: GUI: WPF und XAML

Hallo,
Ich habe ein Control mit n+1 Checkboxen. Eine Checkbox hat die Funktion "Keine Auswahl", die anderen n sind die "Auswahlmöglichkeiten". Die n Checkboxen für die "Auswahlmöglichkeiten" sind gebunden (etwas Background-Info: gebunden an Flags diverser Flag-Enums, dieser Part funktioniert bereits einwandfrei). Die Checkbox "Keine Auswahl" ist nicht gebunden. Ich möchte folgendes haben: Wenn eine oder mehrere IsChecked der n Auswahlmöglichkeit-Checkboxen auf true sind, dann soll sich die IsChecked der "Keine Auswahl" Checkbox automatisch auf false setzen, aber wenn keine der anderen Checkboxen IsChecked=true sind, dann soll sie sich automatisch auf true setzen.

das probiere ich:

<CheckBox Grid.Column="0" Grid.Row="1" Name="cbNothingSelected" IsChecked="False" Content="Keine Auswahl" Margin="0,0,5,0" VerticalAlignment="Center">
                            <CheckBox.Style>
                                <Style TargetType="CheckBox">
                                    <Style.Triggers>
                                        <MultiDataTrigger> 
                                            <MultiDataTrigger.Conditions>
                                                <Condition Binding="{Binding ElementName=cbAuswahl1, Path=IsChecked}" Value="False" />
                                                <Condition Binding="{Binding ElementName=cbAuswahl2, Path=IsChecked}" Value="False" />
                                                <Condition Binding="{Binding ElementName=cbAuswahl3, Path=IsChecked}" Value="False" />
                                            </MultiDataTrigger.Conditions>
                                            <Setter Property="IsChecked" Value="True"></Setter>
                                        </MultiDataTrigger>
                                        <DataTrigger Binding="{Binding ElementName=cbAuswahl1, Path=IsChecked}" Value="True">
                                            <Setter Property="IsChecked" Value="False"></Setter>
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding ElementName=cbAuswahl2, Path=IsChecked}" Value="True">
                                            <Setter Property="IsChecked" Value="False"></Setter>
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding ElementName=cbAuswahl3, Path=IsChecked}" Value="True">
                                            <Setter Property="IsChecked" Value="False"></Setter>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </CheckBox.Style>
                        </CheckBox>
                        <CheckBox Grid.Column="0" Grid.Row="2" Name="cbAuswahl1"...
Also der MultiTrigger soll prüfen ob die Auswahl-Checkboxen alle IsChecked=false haben und falls ja das eigene IsChecked auf true setzen.
Unten sind drei DataTrigger, diese sollen das IsChecked der Checkbox auf false setzen, wenn eine der Checkboxen IsChecked=true haben. 3 DataTrigger da ich damit die OR Beziehung abbilden will, der Multitrigger verknüpft die Conditions ja mit AND.

Es passiert: nichts. Ich kann wild auf den Checkboxen rumklicken, die "Keine Auswahl" Checkbox wird nie automatisch gesetzt/rückgesetzt so wie ich es erwarten würde.
Es werden keine Warnungs oder Fehlermeldungen ausgegeben. Compiliert fehlerfrei, es fliegen keine Exceptions. Die Trigger scheinen einfach nur ignoriert zu werden.
Sieht hier jemand spontan das Problem? Habe bisher noch nicht viel mit Triggern gearbeitet, wenn dann war es nur sowas wie Schriftart fett wenn selektiert oder so (hat bisher immer funktioniert)...

gruß & danke
sth_Weird

Thema: NotifyPropertyChanged für alle Properties, Reihenfolge???
Am im Forum: GUI: WPF und XAML

Danke schonmal für deine Antwort, mein Memento arbeitet intern auch mit einer Kopien des Originalobjekts. Nach außen soll sich die Instanz selber aber nicht ändern.Die Memento-Funktionalität ist bei mir bewusst im Model angesiedelt.
Vielleicht kann jemand noch was genaueres zur Funktionsweise und Reihenfolge sagen...ich wüsste leider nicht wie (verlässlich) testen, außer irgendwelche Debug-Ausgaben einzuführen...
Alternativ wäre es natürlich möglich eine Art Funktion UpdateAll() zu implementieren, die alle PropertyChanged in der Reihenfolge aufruft wie man sie in der Oberfläche braucht, aber wenn das mit dem null schon das gleiche macht, wäre das unnütz und außerdem fehleranfällig...

gruß
sth_Weird

Thema: NotifyPropertyChanged für alle Properties, Reihenfolge???
Am im Forum: GUI: WPF und XAML

Hallo,
ich habe in meiner Applikation das MVVM Pattern verwendet, meine ViewModels implementieren INotifyPropertyChanged.
In die Models haben ich Memento Support eingebaut, wenn ich im View dann auf Abbrechen klicke dann wird im ViewModel der Cancel-Command gefeuert, dieser ruft im Model eine RestoreMemento() Funktion auf die die Werte zurücksetzt. Das führt natürlich nun dazu, dass die Werte in der Oberfläche auch aktualisiert werden müssen... Korrekt müsste nun für alle Properties im VM die im View verwendet werden das NotifyPropertyChanged aufgerufen werden, damit das View mitkriegt, dass sich was geändert hat.
Laut MSDN wird dies auch gemacht (also laut Hilfe "alle Properties"), wenn man beim NotifyPropertyChanged Event in die EventArgs null oder einen leeren String als Parameter übergibt, anstelle des Namens des Properties.
Dazu ein paar Fragen, die leider in bei MSDN nicht beantwortet wird und zu der ich auch nichts weiteres gefunden habe:
- betrifft das nur die Properties, die im View auch verbunden sind (zur Laufzeit weiß die Anwendung ja welche das sind), oder alle Properties, die in der VM Klasse sind (und einen getter haben)?
- Wie ist die Reihenfolge, in welcher die Events gefeuert werden? Alphabetisch, zufällig oder in der Reihenfolge, wie sie im View verbunden sind?

gruß & thx
sth_Weird

Thema: TabControl ItemTemplate 2 alternative DataTemplates (mit key)
Am im Forum: GUI: WPF und XAML

nach Stunden vergeblicher Suche und Probieren hatte ich aufgegeben, nun hab ich kaum hier gepostet und prompt doch noch selbst bzw. auf einer bisher unentdeckten Seite eine Lösung gefunden (nuja so weit war ich ja garnicht entfernt, mein Style und das Ziel waren nur fehlplatziert und das ItemContainerStyle-Element hat außenrum gefehlt...)


<TabControl Grid.Row="8" Grid.Column="1" ItemsSource="{Binding Path=Components, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Margin="10,2,5,2" HorizontalAlignment="Left" VerticalAlignment="top">
                <TabControl.Resources>
                    <DataTemplate x:Key="Type1Template">
                        ...                    </DataTemplate>
                    <DataTemplate x:Key="Type2Template">
                        ...                        </DockPanel>
                    </DataTemplate>
                    </TabControl.Resources>
                    <TabControl.ItemContainerStyle>
                    <Style TargetType="TabItem">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=ChildType}" Value="Type1">
                                <Setter Property="TabItem.HeaderTemplate" Value="{StaticResource Type1Template}" />
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=ChildType}" Value="Type2">
                                <Setter Property="TabItem.HeaderTemplate" Value="{StaticResource Type2Template}" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TabControl.ItemContainerStyle>
            </TabControl>

vielleicht brauchts ja irgendwann mal jemand...

gruß
sth_Weird

Thema: TabControl ItemTemplate 2 alternative DataTemplates (mit key)
Am im Forum: GUI: WPF und XAML

Hallo,

Kurzes Vorwort zu den Rahmenbedingingen: WPF Projekt, MVVM.
ich habe ein TabControl dessen ItemsSource an eine ObservableCollection<...> meines ViewModels gebunden ist. In der ObservableCollection können diverse Unter-ViewModels stecken, aber alle ViewModels haben hier die eine Gemeinsamkeit, dass sie ein Interface implementieren und daher ein Property ChildType (dahinter steckt eine Enumeration) haben.
Nun besteht ein TabItem ja aus einem Header und dem eigentlichen Inhalt. Im Moment habe ich es so, dass der Inhalt automatisch richtig angezeigt wird, da ich in den Resourcen DataTemplates hinterlegt habe für die jeweiligen ViewModels. Die Anzeige des Headers war bisher immer gleich, deshalb hatte ich das ganze so (gekürzt):


<TabControl Grid.Row="8" Grid.Column="1" ItemsSource="{Binding Path=Components, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Margin="10,2,5,2" HorizontalAlignment="Left" VerticalAlignment="top">
<TabControl.ItemTemplate>
                     <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding Number}" />
                            <TextBlock Text="{Binding Text}" />
                        </StackPanel>
                    </DataTemplate>
                </TabControl.ItemTemplate>
            </TabControl>
Das hat funktioniert. Nun aber eine neue Anforderung: Abhängig vom Wert der ChildType-Property soll für das ItemTemplate ein anderes DataTemplate verwendet werden. Dachte erst das wäre ganz einfach und ich könnte einfach einen DataTrigger verwenden. Versucht, Compilerfehler...Unterhalb TabControl.ItemTemplate (FrameworkElement) kann man nur EventTrigger verwenden :(
Wo muss ich nun den DataTrigger hinschreiben, damit es geht?
Ich habe die beiden DataTemplates schon mit keys in den TabControl-Resources angelegt. Wo muss ich nun den DataTrigger unterbringen, damit das richtige DataTemplate im Header angezeigt wird?
Ich habe schon versucht ein Style zu erstellen für TabItem und dort im Setter das TabItem.ItemTemplate zu überschreiben, hat aber leider nicht funktioniert :(
Hier das Style in den TabControl Resources, in der Variante habe ich natürlich das TabControl.Item Template von oben rausgenommen:

<Style TargetType="TabItem">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=ChildType}" Value="Type1">
                                <Setter Property="TabControl.ItemTemplate" Value="{StaticResource Type1Template}" />
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=ChildType}" Value="Type2">
                                <Setter Property="TabControl.ItemTemplate" Value="{StaticResource Type2Template}" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
Leider passiert dann garnichts bzw. das allgemeine ViewModel-DataTemplate wird nun sowohl für die Header als auch für den Content verwendet, als wäre das Style garnicht da oder würde nicht angewandt.
Schreibe ich das TabControl.ItemTemplate von oben wieder dazu, wird es wie zuvor immer so angezeigt.
Kann mir jemand sagen wo ich den Trigger hinpacken muss damit es funktioniert??? Wie gesagt das betrifft nur den Header der Inhalt soll weiterhin wie bisher automatisch angezeigt werden. Und das Template muss auch explizit mit key ausgewählt werden und es sind auch total unterschiedliche Templates, es wird nicht nur eine Farbe oder so ausgetauscht (sonst könnte man den Trigger ja direkt an das Control hängen...).

gruß & danke
sth_Weird