Laden...

Forenbeiträge von wackelkontakt Ingesamt 109 Beiträge

11.11.2012 - 15:55 Uhr

Hallo,

also CleanCode ist defintiv ein gutes Buch um allgemeine Regeln für sauberen Code kennenzulernen. Bei uns in de Firma ist das Pflichtlektüre für neue Kollegen 😃 Der Resharper in Zusammenhang mit Stylecop tut dann den Rest. Wenn ich mir so manche Beispielprojekte aus dem Internet anschaue würde ich mir wünschen das sich mehr Entwickler mit dem Thema beschäftigen würden.

Über deine eigentliche Frage, nämlich der Architektur deines Programmes wirst du da aber meiner Meinung nicht viel finden. Du solltest dir diverse Entwurfsmuster anschauen, welche die Struktur einer Anwendung deutlich verbessern können. Gerade wenn eine Software kontinuierlich wächst und sich dabei die Anforderungen ständig ändern können diese Regeln meiner Meinung nach über den Erfolg oder Mißerfolg einer Software entscheiden. Dabei ist aber natürlich auch immer der Aufwand und Nutzen abzuschätzen. Ein blindes Einsetzen jedes Musters ist natürlich ebenso kontraproduktiv

Model View Presenter ist ein Pattern welches sich für WinForms-Anwendungen eignet.

Ein ORM-Mapper (wie z.B. NHibernate oder EntityFramework) gehört für mich ebenfalls essentiell zu einer sauberen Architektur. Und wenn man sich einen ganz sauberen Programmierstil aneignen möchte dann empfehle ich mal einen Blick auf das Vorgehen bei der testgetriebenen Programmierung.

06.11.2012 - 17:30 Uhr

Hallo,

sieht ja ziemlich abenteurlich aus dein Übungsbeispiel: Warum verwendest du Arrays in deinem Model wenn du dich eh nur auf ein Element bindest?

Vermutlich wird es aber nicht funktionieren da du zwar sagst das sich eine Zahl geändert hat aber nicht das Ergebnis.


        float[] fZahl1 = new float[2];
         public float[] Zahl1
         {
             get { return fZahl1; }
             set
             {
                 fZahl1 = value;
                 OnPropertyChanged("Zahl1");
                 OnPropertyChanged("Ergebniss[0]");
             }
         }

         float[] fZahl2 = new float[2];
         public float[] Zahl2
         {
             get { return fZahl2; }
             set
             {
                 fZahl2 = value;
                 OnPropertyChanged("Zahl2");
                 OnPropertyChanged("Ergebniss[0]");
             }
         }

könnte Abhilfe schaffen (keine Ahnung wie dein CodeBehind/ViewModel aussieht)

Habs nicht probiert... sieht äußerst kurios aus was du da machst 😃

Edit: nein wird vermutlich doch nicht funktionieren da du ja bei Änderung der Werte der Textboxen nicht im Setter der Liste landest. Kleiner Tip: verwerfe erst mal deine Arrays. Dann sollte das Beispiel funktionieren (wie gesagt: in Abhängigkeit was du im CodeBehind bzw. ViewModel treibst). Später kannst du mit Listen arbeiten (IList<float> !!) und in deiner View z.B. mit einem ItemsControl welches dir Listen darstellen kann. Dein obiges Beispiel macht keinen Sinn...

12.07.2012 - 21:27 Uhr

Hallo,

so ziemlich das selbe Problem hatte ich auch schon einmal. Hier die Lösung: Positionierung von Elementen innerhalb von UniformGrid -> wie?

03.04.2012 - 23:40 Uhr

Hallo,

das Thema wurde vor kurzem hier: Daten beim Wechsel von einem UserControl zum anderen speichern besprochen 😉

Da du nach 2 Wochen immer noch nicht bei dem Thema weiter zu sein scheinst habe ich mal dein Beispielprojekt von damals etwas angepaßt (hatte grad mal bissl Langeweile 😉

Dazu aber noch folgendes: ich habe dein Beispiel genommen und wirklich nur so viel umgebaut das es erst mal irgendwie funktioniert (Validierung beim Umschalten der TabItems). Es sind jede Menge Sachen dabei die man anders machen sollte bzw. sogar muß (z.B. MVVM, generische Erzeugung der TabItems). Soviel Langeweile habe ich dann aber auch nicht... das wäre auch nicht der Sinn der Sache alles vorzukauen.
Ich bin mir aber ziemlich sicher das du bei wachsender Projektgröße automatisch auf Probleme stoßen wirst bei denen du dann gewisse Sachen neu überdenken und umbauen mußt. Wie schon damals geschrieben empfehle ich dir beispielsweise das MVVM-Muster für WPF anzuschauen.

02.04.2012 - 20:24 Uhr

Hallo,

ich bin auch ich zielmlicher Neuling mit NHibernate, also kann leider nur vermuten:

So wie es aussieht hast du eine Kreisbeziehung zwischen Store und Product... warum eigentlich? Hört sich für mich redundant an. Mach doch lieber eine Liste mit Stores, welche eine Liste mit Products haben und mehr nicht. Das wäre für mich dann auch eine n:m-Beziehung (ein Store hat mehrere Products und ein Product kann in mehreren Stores sein). Wenn du die Liste von Stores für ein Product benötigst, kannst du das über Datenbankabfragen ebenso auflösen (QueryOver, Sql, LinqToSql,...). Nur so ein Vorschlag... 😉

Ansonsten probiere mal aus dem ManyToMany-Mapping der Objekte ein HasMany zu machen. Hört sich in deinem Fall irgendwie richtiger an.

Gibt es einen Grund das du die Tabellen-und Spaltennamen jedesmal explizit mit angibst?

29.03.2012 - 19:55 Uhr

Sorry für die späte Antwort...

Man nennt das Dependency Injection. Also entweder du benutzt ein DI-Framework (wo ich immer noch der Überzeugung bin das MEF eines ist... deshalb habe ich das Beispiel gleich so verwendet 😃 oder du erzeugst die Instanz direkt an der Stelle wo du sie benötigst:


    var settingService = new SettingService<MySettings>();
    var settings = settingService.Load("C:\\temp\\settings.xml");

Dann kannst du dir das Interface aber eigentlich sparen.

24.03.2012 - 12:01 Uhr

Code sollte man Wart und wiederverwendbar machen, genau das ist die Methode.

Aja... und woran machst du das fest? Für mich treffen solche Eigenschaften auf eine Software zu bei der ich es schaffe die Testabdeckung (Stichwort Unit-Test) bei den theoretischen 100% zu haben. Genau dann habe ich die Module soweit entkoppelt um von Wiederverwendung, Austauschbarkeit, Modularisierung, Erweiterbarkeit usw. zu reden. Ohne mir jetzt genaue Gedanken darüber gemacht zu haben glaube ich wird das bei deiner Implementierung schwer.

aber warum kompliziert wenn es einfach geht...

hier mal die Verwendung meines unten angegeben Vorschlags:

public class Programm
    {
        public Programm(ISettingService<MySettings> settingService)
        {
            var settings = settingService.Load("C:\\temp\\settings.xml");
        }
    }

Typparameter sind gar nicht so schwer oder 😉 Und das alles in meinen Augen sehr elegant ohne Casten zu müssen oder inperformantes Reflection (für die Typbestimmung) zu verwenden. Achso... und hier weiß ich das ich die Testabdeckung auf 100% hochbekomme 😉

24.03.2012 - 10:58 Uhr

Ich würde es so machen:

Hmm oke so kann man das auch machen... bei ner kleinen Probierapplikation mit maximal 3 Klassen. Ne, nicht mal dann würde ich das so machen 😉

Sorry, aber ich finde das ist ein ganz übler Stil:

  1. du gibst einen Typ in die Methode
  2. der Rückgabewert der Methode ist object und muß
  3. deshalb beim Aufruf gecastet

Wie er schreibt möchte er sein System flexibel halten und deshalb finde ich sollte er es auf keinen Fall so machen wie du vorgeschlagen hast (nochmal sorry... aber das ist meine Meinung)

Und ich sehe auch nicht den Unterschied zu meinem Beispiel. Oke, ich habe auf die Ausprogrammierung der Load-Methode verzichtet aber die ist ja ähnlich, bis auf den Rückgabetyp, welcher bei mir halt T ist.
Wenn MEF wirklich das ist was ich vermute dann kann er sich seine Services mit dem entsprechenden Typparameter über Dependency Injection an die Klasse geben lassen und ohne weiteres Zutun auf sehr elegante Art verwenden.

24.03.2012 - 01:24 Uhr

Hallo,

ohne jetzt genau zu wissen was MEF genau ist oder tut (ich dachte mal gehört zu haben das ist ein DI-Framework... aber egal) sieht es so aus das du deinem Interface und Implementierung einen generischen Parameter verpassen mußt:

   
    public interface ISettingService<T>
    {
        T Load(string path);
        void Save(T settings);
    }

    public class SettingService<T> : ISettingService<T> where T : class
    {
        public T Load(string path)
        { ... }

        public void Save(T settings)
        { ... }
    }

Obiger Code funktioniert aber nur wenn eine generische Implementierung für alle Settings-Klassen ausreicht, also du es hinbekommst das sich (bis auf den Typ natürlich) nichts weiter unterscheidet. Falls nicht mußt du für jede Settings-Klasse eine eigene SettingService-Klasse bauen.

Schau dir mal folgenden Beitrag zu Repositories an: LINQ / DataContext / Problem beim Speichern
Da geht es um so ziemlich die selbe Sache wie du vorhast, nur das dort die Persistierung von einem OR-Mapper und bei dir über xml-Serialisierung erfolgen soll. Mal abgesehen von der Dskussion über korrekte Implementierungen usw. siehst du dort verschiedene Ansätze (bin zu faul das alles selber aufzuschreiben 😃

PS: zu dem where T : class schöner wäre es deinen Settings-Klassen ein Interface (z.B.: ISettings) zu verpassen und durch where T : ISettings die erlaubten Typen zu definieren...

22.03.2012 - 14:02 Uhr

Hallo, es geht darum solche Sachen vor der Auslieferung zu erkennen und zu optimieren. Das Problem konnte ziemlich einfach durch Virtualisierung des Wpf-TreeViews behoben werden, aber eben erst nach einer Bug-Meldung des Kunden. Ist uns halt vor Auslieferung, aufgrund fehlender Testdaten nicht aufgefallen. Was ich vergessen habe zu erwähnen ist das ich den Test gern auf GUI-Ebene machen möchte um eben solche Sachen auch mit auszuschließen.

Wie bringt man VS dazu automatisch Testdaten in die Datenbank zu schreiben? Die Testdatengenerierung mit AutoPoco schaue ich mir mal an, danke! Gibt es Tools um solche Sachen auf GUI-Ebene automatisiert zu messen?

22.03.2012 - 11:27 Uhr

Hallo,

letztens traten Performance-Probleme mit unserer Software im Produktivsystem auf (Laden der Daten eines TreeViews dauerte ca. 30 Sekunden). Das Problem war nicht das man das nicht beheben konnte sondern das beim Vorab-Test (mit minimalen Datenmengen) nichts aufgefallen war. Deshalb habe ich nun die Aufgabe eine Übersicht über StateOfTheArt-Tools und -Vorgehen zu Performance-Tests zu erstellen. Dabei geht es vorläufig nur um die Perormance bei großen Datenmengen. Der Test soll in den Build-Prozess integriert werden und über Nacht ausgeführt werden.

Kennt ihr euch eventuell mit solchen Lasttests aus und könnt mir ein paar Tips geben? Das Problem das ich dabei sehe ist das die Daten welche erzeugt werden sollen, ja irgendwo zu dem Domänenmodel passen müssen. Gibt es da Tools oder Frameworks welche reelle Daten erzeugen können (das hört sich zwar nach viel Magie an aber vielleicht habe ich ja Glück).

Ich bin für alle Anregungen dankbar 😉

22.03.2012 - 10:40 Uhr

Hallo,

ein Ansatz wäre es beispielsweise in den UserControls Events zu feuern, auf welche dein MainWindow reagiert (also z.B. bei TextChanged die entsprechenden MenuItems deaktivieren und nach dem Speichern halt wieder aktivieren). Dazu ist es aber notwendig das die Controls beim Umschalten nicht jedesmal neu erstellt werden, sondern als Feld gehalten werden. Wenn du wirklich eine umfangreichere Applikation erstellen möchtest dann solltest du solche grundsätzlichen Sachen beachten. Außerdem könntest du dir auch mal das MVVM-Muster anschauen, welches bei einer gewissen Projektgröße wirklich von Vorteil sein kann.

Viele Grüße!

22.03.2012 - 10:16 Uhr

Hallo,

für die dynamische Größe des Grids findest du hier 2 Lösungsansätze: Wieso kann Grid nicht als ItemsPanel verwendet werden?

11.03.2012 - 21:05 Uhr

Hallo, da ich nicht genau weiß was dein zweites Problem ist hier mal ein paar Vorschläge zum ausblenden der Border. Du könntest:

  • die Visibility des Borders auf eine neue Property binden, welche neben deiner Buttons-Property liegt und halt abhängig des Counts der Liste das gewünschte Verhalten zurückgibt
  • einen Data-Trigger benutzen
  • du kannst die Visibility-Property ebenfalls auf Buttons binden, bräuchtest dann aber einen (z.B. ListCountToVisibilty-) Converter. (Genauso würde es auch funktionieren wen du dem ContentControl einen Namen verpaßt und dich auf die Content-Property bindest)

So ich glaube du hast jetzt genug Auswahlmöglichkeiten 😃 Vielleicht beantwortet das ja dein zweites Problem automatisch.

29.02.2012 - 23:40 Uhr

wie realisierst du das "zuweisen" statt dem neu Erstellen was ja der Standard ist?

Hallo,

also wie gesagt habe ich bisher die Daten (ziemlich redundant) in einer xml-Datei gespeichert. Beim Einlesen habe ich jedes mal neue Objekte erzeugt. Nun schaue ich aber ob die Objekte schon vorhanden sind (bspw. über einen Vergleich der Properties oder eleganter über den Hashcode) und verwende gleichartige Objekte eben nur einmal. So solllten die Daten dann ja auch in der Datenbank landen... Hibernate hat mir die Augen geöffnet 😃

Falls du jetzt immer noch nicht weißt wie ich das mache kann ich dir ja mal beispielhaft zeigen wie mein Importer (von alt auf neu, also lahmarschig auf einigermaßen schnell) funktioniert.

25.02.2012 - 09:10 Uhr

Hallo,

wie es der Zufall so will: ca. eine Stunde bevor ich diesen Beitrag gelesen habe, habe ich beim Komplett-Umbau meines Projektes (u.a. Persistierung der Daten von eigener xml-Datei-Struktur hin zu Datenbank mittels NHibernate... aber eigentlich unwichtig) die Performance ca. um den Faktor 6 verbessert... und das zufälligerweise.. juhu 😄

Ich nutze ebenfalls (sehr intensiv) den DataTemplateSelector, welcher u.a. sogar externe Dateien als Resourcen einliest. Die grausame Performance kam dadurch zustande das eigentlich gleiche Objekte mehrfach erzeugt wurden. Da ich jetzt maximal mit gefährlichem Halbwissen glänzen würde, lass ich den Fakt mal im Raum stehen.

Nachdem ich nun gleiche Objekte nach einmaligem Erstellen nur noch zuweise (und nicht mehr jedes mal neu er- und damit vermutlich dar-stelle) ist die Zeit für das Laden des Projektes von ca. 30s auf 5s geschrumpt.... und ich bin mir sehr sicher da ist noch Potential nach unten!

Kann es bei dir evtl. auch daran liegen?

07.02.2012 - 23:32 Uhr

Wie funktioniert es ohne

  
this.DataContext = m;   
  

d.h. wie kann ich es nur mit xaml code lösen?

Den DataContext setzt man in xaml mittels

    <Windows.DataContext>
        <_local:m/>
    </Windows.DataContext>

Viele Grüße

25.01.2012 - 22:36 Uhr

Hallo,

so etwas ähnliches wurde hier Suche Zeitleiste (Control für WPF) schon mal gesucht. Vielleicht hilft dir der untere Link weiter.

13.01.2012 - 23:18 Uhr

Hallo,

ich habe eine ListView in denen ich die Items per DataTemplate befülle. Nun möchte ich nicht pixelweise scrollen sondern immer nur ganze Items überspringen. Also das keine halben Controls innerhalb der ListView zu sehen sind. Ist dies möglich?

Danke!

02.12.2011 - 11:49 Uhr

Schau dir mal den DataTemplateSelector an, wobei ich jetzt nicht weiß ob der für Silverlight verfügbar ist.

01.12.2011 - 18:09 Uhr

Hallo,

nur zum Verständnis: wenn du die Größe änderst wird nicht in die Setter der beiden Properties gesprungen, richtig?
Hast du schon mal im Ausgabefenster geschaut ob es da irgendwelche Fehlermeldungen zu sehen gibt?

29.11.2011 - 22:47 Uhr

Hallo,

ich möchte mittels WindowsFormsHost in einem Wpf-View ein 'eigenes' WinForms-UserControl benutzen:

        <WindowsFormsHost>
            <Application:LoggingGrid/>
        </WindowsFormsHost>

Funktioniert auch so weit jedoch habe ich das Problem das der Konstruktor der WinForms-Klasse LoggingGrid ständig aufgerufen wird.
Zur Erklärung: ich verwende MVVM und das Control wird in einer Workspace-View verwendet. Immer wenn ich den Workspace wechsle wird das Objekt neu erzeugt. Kann mir jemand sagen wie ich das umgehen kann? Ich möchte (ähnlich dem Workspace-ViewModel) dieses Control während der Laufzeit einmal erzeugen und benutzen können.

Ich hoffe ich habe das Problem nicht allzu umständlich dargestellt.

31.10.2011 - 18:38 Uhr

Hallo,

Der TemplateSelector scheint nett, allerdings habe ich noch keinen Weg gefunden ihm einen Wert mitzugeben nachdem er unterscheiden soll ...

<DataGrid RowDetailsTemplateSelector="{StaticResource templateSelector}" .../>

Mitgegeben werden nun die einzelnen Objekte des Datenquelle des Grids, also die Objekte die eine Zeile in deinem Grid repräsentieren. Zumindestens wenn du es nicht expliziet änderst.

25.10.2011 - 17:12 Uhr

Hallo,

also was du möchtest ist eigentlich klar. Obwohl die Frage eigentlich ziemlich einfach ist, ist die Antwort nicht ganz so leicht. Der Grund ist das dir die Wpf da zu viele Möglichkeiten bietet als DIE eine Lösung dir jetzt präsentieren zu können. Du kannst da deiner Fanatasie freien Lauf lassen 😉

So ein ähnliches UserControl wie du es brauchst habe ich beispielsweise mit einem StackPanel erledigt. Auf der linken Seite ist dann eine ListView, welcher ich eine ObservableCollection als ItemsSource hinzugefügt habe. In Abhängigkeit der Auswahl werden dann auf der rechten Seite in einer weiteren ListView die zugehörigen Items angezeigt (ähnlich wie in Expression Blend das Assets-Control).

Vielleicht kannst du damit ja was anfangen:

    
    <StackPanel Orientation="Horizontal">
        <ListView 
            ItemsSource="{Binding MainViewModel.ModuleService.AvailableGroups}" 
            SelectedValue="{Binding MainViewModel.ModuleService.SelectedGroup}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Label 
                        Content="{Binding}" 
                        HorizontalAlignment="Stretch">
                    </Label>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <ListView 
            ItemsSource="{Binding MainViewModel.ModuleService.CellItems}"
            SelectedItem="{Binding ParentBoard.SelectedSelectorCell}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <_Views:CellSelectorItemView/>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid/>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>
    </StackPanel>

Aber wie gesagt ist das nur eine von mehreren Möglichkeiten. Mit einem Grid hätte ich das z.B. genauso hinbekommen.

25.10.2011 - 10:43 Uhr

Hallo,

ich glaube ich kenne das Problem. Es liegt daran das während der Designzeit irgendwelche Datenzugriffe nicht funktionieren weil man beispeilsweise erst während der Laufzeit Datenquellen angibt. Abhilfe schafft hier diese Methoden (meistens im Konstruktor) mittels der IsInDesignModeProperty während der Entwicklungszeit 'auszukommentieren'

public static bool IsInDesignMode
        {
            get
            {
                return (bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue;
            }
        }
19.10.2011 - 15:21 Uhr

Hallo winSharp,

super Sache, funktioniert so wie es soll 👍

Danke!

Mal so nebenbei: Dieser Blogeintrag: A simpler (and dynamic) Grid control for WPF und der Tip mit dem ItemContainerStyle sind die Lösung für ein früheres Thema Positionierung von Elementen innerhalb von UniformGrid -> wie? bei dem du mir schon mal helfen wolltest, ich aber aufgrund von Zeit- und Wissensproblemen aber erst mal zur Seite geschoben habe. Da aber das Sortieren der Liste (als Übergangslösung) extrem lange dauert, bin ich das Thema noch mal angegangen. Mit der jetzigen Lösung bin ich erst mal ganz zufrieden, bin mal auf die Performance gespannt.

18.10.2011 - 20:50 Uhr

Hallo,

ich würde gern ein Grid als ItemsPanel verwenden. Jedoch geht das schief. Hier ein beispielhafter Aufbau (Das Beispiel macht vielleicht nicht viel Sinn aber ich wollte die Sache einnfach halten. ):

<ListView 
                ItemsSource ="{Binding Path=Cells}" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding Cell.VisuName}" 
                                Grid.Column="{Binding Cell.PositionX}"
                                Grid.Row="{Binding Cell.PositionY}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                                <RowDefinition/>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
            </ListView>

Es werden nun aber keine Columns und Rows angelegt, sondern die Items werden in einem 1x1-Grid übereinander gestapelt. Verwende ich ein UniformGrid (natürlich ohne Zuweisung der Position) funktioniert alles wie es soll.

Kann mir jemand erklären warum das mit einem Grid schief geht?

12.10.2011 - 00:30 Uhr

Hallo, ich hänge schon eine ganze Weile an einem Problem und hoffe ihr könnt mir helfen.

Ich würde gern Visu-Elemente in z-Richtung stapeln. Als ein Visu-Element würde ich gern ein FrameworkElement (beispielsweise Path) welches als Resource definiert ist mit verschiedenen Transformationen versehen und anzeigen.

Die Klasse mit den Informationen für jedes Element sieht so aus:

    public class XamlItem
    {
        public string ResourceName { get; set; }
        public int Rotation { get; set; }
        public int TranslationX { get; set; }
        public int TranslationY { get; set; }
    }

2 Sachen habe ich bisher versucht:

  1. über einen Converter die einzelnen Elemente hinzuzufügen:
                <ItemsControl 
                    ItemsSource="{Binding Cell.XamlItems}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Label
                                Content="{Binding Converter={StaticResource converter}}"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Grid/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>

Jedoch wird hier das das FrameworkElement (obwohl wie gesagt als Resource definiert) nur einmal dargestellt?! Sollte es nicht so sein das Resourcen mehrfach verwendet werden können?

  1. habe ich versucht das Ganze über den DataTemplateSelector zu lösen (vermutlich auch die bessere Variante)
<ContentPresenter Content="{Binding Cell}" ContentTemplateSelector="{StaticResource templateSelector}"

Ich bekomme es jedoch in der SelectTemplate - Methode nicht hin die Resourcen zu dem DataTemplate im Code hinzuzufügen:

                        DataTemplate dt = new DataTemplate();

                        FrameworkElement element = ((Control)obj).TryFindResource(xamlItem.ResourceName) as FrameworkElement;
                        RotateTransform rt = new RotateTransform(xamlItem.Rotation);
                        element.RenderTransform = rt;

Tja und wie jetzt weiter? Ich vermute mal über die FrameworkElementFactory aber iregndwie bekomme ich das Element nicht hinzugefügt (ich hoffe ja das die Resource in diesem Fall mehrfach verwendet werden kann).

Kann mir jemand weiterhelfen? Oder gibt es noch eine bessere Lösung?

Danke fürs Durchlesen 😉

06.10.2011 - 11:07 Uhr

Hallo Mazo,

was klappt denn nicht? Kompilierfehler oder macht er nicht so wie es soll? Gibt es Fehlermeldungen im Ausgabefenster?

Ich vermute aber mal du mußt den DataContext auf Box setzen und den BindingPath dann bspw. auf ActiveBackgroundColor.

EDIT:

(definiert in App.xaml)

überlesen 😃 also dort stellst du die Verbindung zur Datenbank her? Kannst du das dann in deinem Toolkit-Projekt evtl. über die ResourceDictionary.MergedDictionaries Property hinbekommen?

04.10.2011 - 15:56 Uhr

Ich glaube mich zu erinnern das die Angabe des DataTemplates in den Resourcen in Silverlight nicht geht (sondern nur in Wpf). Deshalb hier noch mal eine SL-fähige Variante (-:


            <ListView ItemsSource="{Binding ToolTipGroups}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Key}" />
                            <TextBlock Text="{Binding Value}" />
                        </StackPanel>
                        <!-- Hier kann stattdessen auch ein UserControl angegeben werden:
             <Views:ToolTipGroupView/>-->
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
04.10.2011 - 15:40 Uhr

Hallo,

nicht ganz 😃

Das DataTemplate wird meistens als Resource festgelegt. Hier mal für die Group-Collection:


    <UserControl.Resources>
        <DataTemplate DataType="{x:Type ToolTipGroup}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Key}" />
                <TextBlock Text="{Binding Value}" />
            </StackPanel>
            <!-- Hier kann stattdessen auch ein UserControl angegeben werden:
            <Views:ToolTipGroupView/>-->
        </DataTemplate>
    </UserControl.Resources>
	
	 <!-- Hier ein Container und zuweisen der Collection als Source-->
	<ListView ItemsSource="{Binding ToolTipGroups}"/>

Jetzt werden alle Objekte des ToolTipGroup-Typs mit dem StackPanel dargestellt. Das ist bei dir noch nicht genug, da ja die Collection weitere Listen enthält. Du mußt halt weiter verschachteln.

Da du offensichtlich nicht MVVM anwendest und ich auf der anderen Seite nicht Nicht-MVVM programmieren kann hoffe ich mal das dieser Lösungsansatz auch der richtige für dich ist.

04.10.2011 - 14:10 Uhr

Hallo,

du kannst das StackPanel in ein DataTemplate packen. Damit tust du sozusagen festlegen wie Daten visualisiert werden sollen.

28.09.2011 - 13:50 Uhr

Hallo,

nachdem mein Model jetzt soweit funktioniert möchte ich mich bei meinem Projekt nun an die Visualisierung machen. Dabei möchte ich Beziehungen zwischen einzelnen Elementen grafisch darstellen. Ich habe Gruppen in denen ich eine beliebige Anzahl von Fragen definieren kann. Diese Fragen sollen bei Bedarf als Bedingungen in anderen Gruppen auszuwählen sein. Zur Zeit reihe ich die Gruppen nur nacheinander auf. Mittels Paint habe ich das mal etwas (stümperhaft 😃 zerlegt um zu zeigen was ich meine.

Hat von euch jemand eine Idee wie ich sowas in der Art umsetzen kann und wie der Aufwand dafür ist?

Bin auch gern offen für andere Vorschläge was die Visualisierung betrifft.

27.09.2011 - 21:42 Uhr

Hier auch noch mal eine 'heiße' Diskussion zu dem Thema leere Codebehind: Ist MVVM ein Muss bei WPF Anwendungen

Zu dem zweiten Punkt kann ich gfoidl nur zustimmen. Da du geschrieben hast das du dein Projekt in Richtung MVVM umgestaltet hast gehe ich mal davon aus das du noch nicht damit fertig bist (oder eben noch nicht richtig verstanden 😉

27.09.2011 - 14:13 Uhr

Läßt du die Spalten des DataGrids automatisch generieren?
Wenn du die Time-Spalte an die Time-Property der Objekte deiner Collection gebunden hast sollte das eigentlich automatisch funktionieren, ganz ohne Event-Handling o.ä.

Ansonsten hilft vielleicht auch mal ein Blick ins Ausgabefenster, vielleicht kommt er mit den Formaten nicht zurecht.

27.09.2011 - 13:51 Uhr

Da die ViewModel aber alles Elemente deines MainViewModels sind und die Views alle auf deinem MainView liegen ist der DataContext derselbe.

27.09.2011 - 13:44 Uhr

Zum Thema: Ok, also den Datacontext, der zu Komponenten im MainWindow gehört, trag ich dann auch im Konstruktor des MainWindow ein?
Das klingt auf Anhieb zwar logisch, aber ich meine mal gelesen zu haben, dass die Code-behind Dateien, die an den Views hängen immer leer sind.

Du kannst den DataContext auch in der MainWindow.xaml setzen:

    <Window.DataContext>
        <ViewModels:MainWindowViewModel/>
    </Window.DataContext>
27.09.2011 - 13:37 Uhr

Hallo,

was funktioniert denn nicht genau? Wird die Statusleiste nicht angezeigt?

Ich will jetzt nichts falsches sagen aber so wie du die Sachen instanziierst und zuweist ist es mindestens unschön. Die App.xaml.cs ist genauso eine Code-Behind-Datei und sollte deshalb nach MVVM weitgehend leer bleiben. Du solltest in deinem MainWindowViewModel die ViewModelStatusleiste instanziieren. Da StatusleisteView ein Element des MainViews ist brauchst du den DataContext nicht explizit angeben, der wird über das DataTemplate automatisch gesetzt (wenn du den DataContext natürlich im MainView auf das MainWindowViewModel gesetzt hast).

Ich hoffe ich habe dich jetzt nicht allzusehr verwirrt 😃

22.09.2011 - 22:56 Uhr

Hallo,

ich kann mir eventuell vorstellen was dein Problem ist. Aber bevor ich jetzt anfange mir ein Beispiel aus den Fingern zu saugen: kannst du nicht mal die paar Zeilen des DataGrids und des Templates hier posten?

21.09.2011 - 12:21 Uhr

Hallo,

sieht nach einem Gantt-Diagramm aus. Hab mal fix geschaut, vielleicht kannst du ja das WPF Gantt chart auf codeplex verwenden(?)

21.09.2011 - 10:04 Uhr

Hallo,

du kannst für so etwas die Viewbox verwenden.

20.09.2011 - 08:38 Uhr

Hallo Joetempes,

vielen Dank für den Ansatz... hört sich beim Überfliegen wirklich nicht so trivial an. Aufgrund des ersten Links in dem oberen Post bin ich auch irgendwie davon ausgegangen das du das mit Wpf umgesetzt hast. Denkst du es Sinn macht deinen Ansatz auf auch Wpf (inklusive MVVM) zu übertragen?

Falls ja kannst du ja wirklich mal ein Video erstellen, wenn es so aussieht wie das was ich benötige kann ich dich ja weiterhin noch bißchen nerven 😉

20.09.2011 - 08:31 Uhr

Ich habe den Fehler gefunden, es lag an einer Viewbox die an einer anderen Stelle um das gesamte Control herumgelegt war.

Nun sieht es aus wie es soll... 😃

19.09.2011 - 09:26 Uhr

Hallo,

ich habe mir ein Popup zurechtgebastelt welches als eine Art zweites Contextmenu (zu öffnen per Linksklick) dienen soll. Hier mal des vereinfachte Control:


    <UserControl.Resources>
        <DataTemplate DataType="{x:Type _ViewModels:CellSelectViewModel}">
            <_Views:CellSelectView/>
        </DataTemplate>
        <ControlTemplate x:Key="CellSelectTemplate" TargetType="ContentControl">
            <Grid>
                <ContentPresenter Content="{TemplateBinding Content}"/>
                <Popup Name="Popup" Placement="MousePoint" >
                    <ContentPresenter Content="{Binding CellSelectViewModel}"/>
                </Popup>
            </Grid>
            <ControlTemplate.Triggers>
                <!---->
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </UserControl.Resources>
    <ContentControl Template="{StaticResource CellSelectTemplate}">
        <ListView ItemsSource ="{Binding Path=Cells}" />
    </ContentControl>

Das UserControl welches ich zur Anzeige benutze (CellSelectView) sieht vereinfacht so aus:


<UserControl>
    <Viewbox Width="800">
        <StackPanel Orientation="Horizontal">
            <ListView ItemsSource="{Binding AvailableGroups}"/>
            <ListView ItemsSource="{Binding CellItems}"/>
        </StackPanel>
    </Viewbox>
</UserControl>

Das Problem ist das die Größe des Popups abhängig von dem aufrufenden Control ist (siehe Anhang). Ich habe eigentlich schon an sämtlichen Stellen versucht die Größe fest zu setzen, bisher mit wenig Erfolg. Kann mir jemand sagen wie ich es hinbekomme die Größe fest, also ähnlich einem 'normalen' Contextmenus einzustellen?

Vielen Dank!

18.09.2011 - 18:28 Uhr

Hallo Joetempes,

ich habe auch schon mal eine Weile damit verbracht ein paar Ansätze für das 'IPhone-Verhalten' zu finden und bin darauf gestossen: Adding transitions to a MVVM based dialog

Da es aber nicht über Maus-/Touchgesten zu steuern ist, ist es nicht das was ich eigentlich wollte. Könntest du deshalb evtl. mal grob zeigen wie du deine Applikation aufgebaut hast und das mit den Gesten machst? Ich bin schwer daran interessiert 😉

Danke!

16.09.2011 - 15:38 Uhr

Wieso erstellst du überhaupt das DataTemplate an der Stelle? Reicht nicht einfach:

<UserControl 
...>
    <StackPanel Background="Yellow">
        <TextBlock HorizontalAlignment="Left" Margin="10" Text="{Binding Path=Figur.Name}" VerticalAlignment="Top" />
    </StackPanel>
</UserControl>
16.09.2011 - 14:04 Uhr

Also wie gesagt vergiss bitte meine obige (schon gelöschte) Antwort (Ich schreibe die DataTemplates immer in die Resourcen, da ist diese Syntax so notwendig). So wie du es machst ist es eigentlich ok.

Also ich gehe mal davon aus das dein FigurControl eigentlich FigurenSetView heißen soll richtig? Da wird eigentlich nur der Konstruktor der CodeBehind-Datei aufgerufen. Wenn dein überladener Konstruktor im ViewModel nicht aufgerufen wird machst du beim Erstellen etwas falsch. Du kannst ja mal zeigen wie du die Liste der ViewModels füllst.

16.09.2011 - 13:01 Uhr

Gedanklich kann ich mich zwar irgendwie noch nicht so ganz damit anfreunden, dass ich die ViewModels verschachteln muss, aber daran muss ich mich wohl gewöhnen.

Tja daran wirst du dich wohl gewöhnen müssen 😃 wie willst du es aber auch anders machen? Wenn du verschachtelte Modelklassen hast wird es erst richig schön... wie ich letztens auch festgestellt habe: MVVM - Designfrage

EDIT: Sorry, ich habe deine Frage falsch verstanden/überlesen gehabt, deshalb die vermeintliche Antwort gelöscht.

15.09.2011 - 21:14 Uhr

Hallo phear...

den Fehler den du machst ist es das du in deinem MainPageViewModel eine Collection deiner ModelObjekte erstellst und als ItemSource der ListView zuweist. Die Lösung sollte meiner Meinung nach folgendermaßen aussehen:

    public interface IMainPageViewModel
    {
        ObservableCollection<FigurenSetControlViewModel> FigurenSetControlViewModels { get; set; }
    }
    public interface IFigurenSetControlViewModel
    {
        string Name { get; }
        ObservableCollection<Figur> Figuren { get; }
        string Zusatz { get; }
        FigurenSet FigurenSet { get; set; }
    }
        <ListBox ItemsSource="{Binding FigurenSetControlViewModels}" Background="LightBlue">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel Background="White" Margin="10">
                            <TextBlock Text="{Binding FigurenSet.Name}" />
                            <!-- Wie kommt man an das ViewModel des jeweiligen FigurenSetControls? -->
                            <TextBlock Text="{Binding Zusatz}" /> <!-- die Property ist in diesem Context nun bekannt ;-) -->
                            <!-- ... -->
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
15.09.2011 - 13:17 Uhr

Also du benutzt eine DataTable... puuh, da kenne ich mich in Wpf leider nicht so aus. Kannst du mal grob zeigen wie du die füllst und dem DataGrid zuweist?