Laden...
R
robin_ myCSharp.de - Member
Technischer Produkt Designer Bergisch Gladbach Dabei seit 26.07.2017 38 Beiträge
Benutzerbeschreibung
Robin, 21 Jahre alt, hobby-mäßiger Programmierer lernt nun C#.

Forenbeiträge von robin_ Ingesamt 38 Beiträge

12.09.2017 - 18:48 Uhr

Hallo,

Ich habe die letzten Tage damit verbracht, ein eigenes UserControl, bestehend aus einer TextBox und 2 Buttons, zu bauen. Nun habe ich verschiedene Fragen diesbezüglich und würde gerne am liebsten Wissen, wo ich diesbezüglich nachlesen kann 😃

Folgendes: Ich habe zb. eine DependencyProperty (string) die an die Eigenschaft text der TextBox gebunden ist.

Wenn ich nun in einem Projekt mein UserControl im XAML verwende, kann ich die Property setzten:

<ns:MeinUserControll MeineDependencyProperty="xxx" />

Was muss ich im Code machen, um diesen Wert zu kriegen? Weil die string - Property zb. nicht mit dem Wert befüllt wird, der im der XAML angegeben wird. (Vielleicht habe ich das auch ein Konzeptionelles Problem).

Weitere Frage:
Ich habe aktuell in der .cs-Datei des UserControls eine Eigenschaft, die (mittels DataTrigger) das aussehen der TextBox verändert. Dieses ist also an die Eigenschaft 'MeineEigenschaft' gebunden (DataContext ist also die Code-Behind-Datei). Nun habe ich das Problem, dass mein UserControl in einem ListView ist. Der ListView ist an eine ListCollectionView - Eigenschaft meines ViewModels gebunden. Somit sucht die Textbox meines UserControls das angegebene Binding in den Objekten des ListCollectionViews (Model-Klasse) und eben nicht in der CodeBehind-Datei... Der DataContext ist sozusagen durch (die anderen Elemente in der XAML) überschrieben worden.

Oder anders gesagt: Mein UserControl liegt in einer ListView, an die gebunden wird. Deshalb findet das Binding in meinem Control die Eigenschaft nicht mehr (denn der DataContext ist in dem Fall das Objekt der ObservableCollection<objekt> / Item des ListCollectionView).

Das Problem ist recht schwer zu umschreiben, ich vermute auch eher allgemeine Fehler in meiner Herangehensweise/ Verständnis. Aus früheren Fragen hatte ich mal entnommen, dass man nicht für jedes Element im Baum den DataContext setzt, sondern einmal fürs Top-Element und sich dann "durchhangelt" mit dem PropertyPath. Somit haben aber Sub-Elemente automatisch diesen Bereich und können nur noch "tiefer" gehen.

Ich habe das Problem überbrückt, indem ich der Model-Klasse der ObservableCollection<> eine Referenz vom Typ des ViewModels mitgebe und sozusagen über die ModelKlasse.ReferenzAufVM ans ViewModel binde - was natürlich sehr unschön ist.

Ich vermute, dass meine Herangehensweise da evt. nicht sauber ist und es deshalb nun Probleme gibt - Vielleicht habt ihr ja paar Tipps oder was zu lesen oder so 😉

Danke:)

12.09.2017 - 15:32 Uhr

Ich habe jetzt einfach die "umständliche" Timer - Variante genommen, das klappt sehr gut. Wie gesagt, auf +-*/ 15 ms kommt es nicht an 😉

Erstaunlich finde ich, dass der RepeatButton anscheinend nicht so funktioniert, wie er es eig. sollte.

LG

11.09.2017 - 19:05 Uhr

Sehr skurril...

Habe soeben ein neues WPF-Projekt erstellt welches ausschließlich 2 Rows in einer Grid enthält, in jeder einen RepeatButton mit einem Intervall von 200.

Das sind die Ergebnisse (gemessen mit Stopwatch):> Fehlermeldung:

Für Button 1:
1030
828
755
1129
628
589
1404
2424
1184
1539

Für Button 2:
884
334
1066
1155
860
2902
2057
1671

Vielleicht kann mal jemand das eben nachbauen und gegenchecken?

private void UP_Click(object sender, RoutedEventArgs e)
        {
            if (_Stopwatch.IsRunning)
            {
                _Stopwatch.Stop();
                _Milliseconds = _Stopwatch.ElapsedMilliseconds;
                Debug.WriteLine(_Milliseconds);
                _Stopwatch = Stopwatch.StartNew();
            }

        }

        private void DOWN_Click(object sender, RoutedEventArgs e)
        {
            if (_Stopwatch.IsRunning)
            {
                _Stopwatch.Stop();
                _Milliseconds = _Stopwatch.ElapsedMilliseconds;
                Debug.WriteLine(_Milliseconds);
                _Stopwatch = Stopwatch.StartNew();
            }
        }

DANKE

11.09.2017 - 18:09 Uhr

Danke Palladin, diese Variante ist sehr einfach und funktioniert. Auf die exakte Wiederholungsrate kommt es nicht an - ist ein Counter der eine Zeitangabe um +5min oder eben -5min verändert.

Dabei ist ein halbwegs gleiches Intervall für die Benutzerfreundlichkeit nicht verkehrt. Da kommt es auf +-0,05 sec nicht an 😉

Wobei das schon sehr komisch ist, ich werde das noch mal genauer unter die Lupe nehmen und recherchieren.

LG

10.09.2017 - 12:09 Uhr

Ich hatte die Methoden absichtlich nicht kopiert, weil das komische Verhalten selbst dann auftritt, wenn ich in der Click-Methode den Counter NICHT verändere (Und damit die ganzen Methoden nicht aufgerufen werden).

Den Vorschlag mit dem Testprojekt habe ich umgesetzt und dabei die Klasse Stopwatch benutzt. Es kommt das gleiche Ergebnis raus...
Es streut zwischen 0,2s und 1,6 sec beim Eingestellten Intervall von 200 Millisekunden.

Anbei das Testprojekt.

Danke

09.09.2017 - 12:51 Uhr

Also im UserControl sind 2 RepeatButton und eine TextBox. Den Code vom RepeatButton seht ihr oben.

Durch das drücken das Buttons wird die DependencyProperty verändert, damit wird die Callback-Methode aufgerufen:

 private static void TimeValuePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)

Darauf folgt das Event, welches in der TestApp aufgerufen wird:

private void TimePicker_TimeValueChanged(object sender, RoutedPropertyChangedEventArgs<string> e)

und zu guter Letzt daraufhin das Event der TextBox:

        private void txtBoxTime_TextChanged(object sender, TextChangedEventArgs e)

Ich kann den Wert entweder über die TextBox ändern, oder über die Buttons. Nun fällt direkt auf, dass das Event der TextBox TextChanged nicht aufgerufen werden muss und soll, wenn der Wert "im Code" (Durch die BUttons) geändert wird.

Ich muss also ein anderes Event suchen, welches nur bei direkter Eingabe und Änderungen in der Box triggered.

Die Verkettung von aufgerufenen Methoden ist aber nicht der Grund.

Die Button-Methode sieht wie folgt aus:

private void btnUp_Click(object sender, RoutedEventArgs e)
        {
            Console.WriteLine("----------------BUTTON UP");
            Time = Time.AddMinutes(5);
           
        }

Wenn ich den Zuweisungsbefehl rausnehme, werden die oben erläuterten Methoden nicht aufgerufen und trotzdem ist es unregelmäßig...

//EDIT: Achja, und wenn ich den Zuweisungsbefehl drin habe, also die verketteten Methodenaufrufe stattfinden, und ich sehr schnell klicke (Deutlich schneller als das eingestellte Intervall) so klappt die Wertänderung ja auch. Es liegt also nicht an den aufgerufenen Methoden durch Event-Callbacks etc. sondern anscheinend am Control selbst?

08.09.2017 - 19:27 Uhr

Hallo,

bin gerade dabei ein UserControl aufzubauen. Dieses beinhaltet unter anderem 2 RepeatButtons:

<RepeatButton Name="btnUp" Grid.Column="1" Click="btnUp_Click" BorderBrush="Black" Interval="50" />

Der Button erhöht einen Counter.

Um die "Repeat-Rate" zu ändern, habe ich Interval gefunden:

Gets or sets the amount of time, in milliseconds, between repeats once repeating starts. The value must be non-negative.

Nun habe ich das Problem, dass die Ausführung sehr ungleichmäßig ist. Und das unabhängig vom Interval. So kommt es vor, dass die Ausführungszeit der Click-Methode zwischen 0.1 - 2 Sekunden dauert (bei einem Interval=100).

Da dies auch bei höheren Intervallen passiert und ebenfalls auftritt, wenn in der Click-Methode nichts passiert, frage ich mich, woran so ein Verhalten liegen kann?

Vielleicht hatte ja schon jemand änliche Problemchen.

Schönes WE!

07.09.2017 - 19:12 Uhr

Ja, das ist mir bewusst.

Und ja, ich änder den Namespace in der .xaml und in der .xaml.cs - Datei.

Dachte das wäre hiermit klar geworden:

den Namespace in der cs-Datei anpasse (z.B. ein "a" hintendran hänge) und anschließend in der XAML x:Class - deklaration

Also, ja in der kurzen Zeit, wo die beiden Dateien nicht synchron sind, ist es ja logisch, das ein Fehler kommt 😉

Mir geht es aber um den Zeitpunkt, wo beide Namespaces exakt gleich sind und der Fehler nach dem kompilieren und VS neustarten immer noch existiert.

Und sobald ich den NameSpace auf den ursprünglichen änder (Der ursprünglich ja mal gleich der ProjektDatei war), geht wieder alles...

LG

07.09.2017 - 16:36 Uhr

Bin gerade verschiedene Sachen am probieren, weil ich wie unconnected das Gefühl habe, dass VS hier sehr durcheinander kommt.

Wenn ich ein neues Control erstelle, und den Namespace in der cs-Datei anpasse (z.B. ein "a" hintendran hänge) und anschließend in der XAML x:Class - deklaration, kriege ich eine Fehlermeldung. Dieses mal jedoch > Fehlermeldung:

CS0103: Der Name "InitializeComponent" ist im aktuellen Context nicht vorhanden.

Das dürfte eigentlich m.E.n. nicht passieren, oder?
Ich habe es jetzt paar mal ausprobiert und mir ist aufgefallen, dass ich den Namespace nicht ändern kann bzw. der Namespace immer gleich der ProjektDatei benannt sein muss.

Vielleicht ist das normal und mir war es dann bis jetzt nicht bekannt 😉 Finde das nur komisch.

LG

/EDIT: Die Vermutung mit der ProjektDatei scheint nicht zu stimmen, sobald man die Projektdatei umbenennt. Glaube ich bin da total auf dem Holzweg... Kann mich jemand aufklären?

06.09.2017 - 20:42 Uhr

Hm,

also

x:Class="<namespace>.<classname>"

ist doch richtig, oder?

Es hat ja funktioniert und habe am namespace nichts geändert... ich vermute was anderes, weiß leider nicht was.

LG

06.09.2017 - 17:53 Uhr

Hi Leute,

ich bin gerade dabei, mir ein eigenes UserControl zu basteln.

Leider kann ich seit kurzem nicht mehr kompilieren, aufgrund des Fehlers (Siehe Anhang).

Da ich den Fehler jetzt schon öfters hatte und nichts damit anzufangen weiß, bitte ich euch um Rat.

Anbei der XAML-Code, wo der Fehler in Zeile 10 auftreten soll.

<UserControl x:Class="TimePicker.TimePicker"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="30" d:DesignWidth="71"
             Name="timePicker">
    <StackPanel>
      
            <Grid>
                <Grid.RowDefinitions>
                   ...
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                  ...
                </Grid.ColumnDefinitions>

                <TextBox Name="txtBoxTime"
                        Text="{Binding TimeValue, ElementName=timePicker}"
                         
                         />

                <RepeatButton Name="btnUp" Grid.Column="1" Click="btnUp_Click" BorderBrush="Black" >
                    
                </RepeatButton>
               
                <RepeatButton Name="btnDown" Grid.Row="1" Grid.Column="1" Click="btnDown_Click" BorderBrush="Black">
                 </RepeatButton>
            </Grid>
            

    </StackPanel>
</UserControl>

Danke und LG

P.S: Das Control heißt "TimePicker", genau wie der Namespace in der CB-Datei.

Fehlermeldung:
CS0426: Der Typname "x" ist im Typ "x" nicht vorhanden.

04.09.2017 - 19:42 Uhr

OK, also was EF ist habe ich glaube ich verstanden, es scheint mir vom Prinzip her gleich zu sein wie CoreData in Objective-C 😃

Ja, mir geht es vor allem darum, einen Overhead für diese "paar" Datensätze zu vermeiden.

Würde ich nun zb. mit SQL Server Express eine Datenbank erstellen und in meiner Anwendung mittels ADO.net o.ä. verwenden, so müsste auf dem Client-PC ebenfalls ein SQL-Server-Dienst installiert sein und laufen (richtig?) --> Für mich sieht das nach recht hohem Aufwand aus.

Danke für die schnelle Antwort!

/EDIT:

Sorry, mir ist das immer noch nicht ganz klar. Also, ja, man kann mit EF verschiedenste Datenbanken verwalten und das EF fungiert zwischen dem Code und der DB als Wrapper. Muss ich nun einen SQL Server - Dienst installiert haben (beim Client, wenn ich eine Datenbank als Datei als Ressource (wie ein Bild zb.) beilege? ) ?

Danke

04.09.2017 - 19:28 Uhr

Danke Pinki, das sieht sehr interessant aus!

04.09.2017 - 18:54 Uhr

Hallo,

Ich bin Datenbanken-Neuling und bräuchte mal kurz eure Meinung 😃

Also folgendes: Ich habe mich gerade grob eingelesen, um die Unterschiede der verschiedenen Möglichkeiten zu verstehen um dann eine Variante auszuwählen und mich damit tiefer zu beschäftigen.

Sehe ich es richtig, dass wenn man das Entity Framework verwendet und das EDM selbst erstellt (und nicht durch eine Datenbank generieren lässt), dass man mit der eigentlichen Datenbank nichts mehr zu tun hat? Ich meine damit zum einen den Zugriff auf Daten in der DB aber auch zb. den Installationsprozess: Bei SQL muss man ja zb. immer einen im Hintergrund laufenden Dienst haben (hoffe das habe ich richtig verstanden) und somit bei der Installation die DLL-Dateien bereitstellen, sofern dies rechtlich möglich ist.

Für meinen Anwendungsfall wären es vielleicht mal paar hundert Datensätze, welche durch verschiedene Objekte abgebildet werden würden, welche wiederum aus strings, ints, doubles etc. bestehen. Außerdem würde mindestens ein Bild in einem solchen Datensatz vorhanden sein (eher als Thumbnail gedacht).

Was haltet ihr von meinen Überlegungen?
Danke

MfG Robin

31.08.2017 - 17:00 Uhr

Habe das von dir verlinkte Projekt mal angeschaut... Ist das VB und ist, außer der Syntax, alles gleich zu C#?

Bzw, habe meinen vorherigen Beitrag noch editiert

31.08.2017 - 16:39 Uhr

Ich möchte auch weder was fertiges Vorgetipptes noch, dass Code debugged wird (der als Lösung unter meine Frage gepostet wurde).

Du hast recht, man findet viel Drag&Drop gedöns, auch MVVM-Konform, in denen die ich gefunden habe allerdings nur von ListView1 nach ListView2 etc...

Vielleicht ist es durch meinen Post nicht wirklich klar geworden, aber mir geht es hierbei hauptsächlich um die Logik, welche bei einer D&D - Implementierung berücksichtigt werden muss. Z.B.: "Verschiebe" ich die Daten in der Datenquelle oder im ListCollectionView (Klar, jenachdem was für ein Anwendungsfall vorliegt, muss man das eine oder andere machen).

Gibt es in der Microsoft - Doku einen Artikel über die Implementierung und dessen benötigte Logik zum Thema D&D?

Danke
MfG

30.08.2017 - 17:29 Uhr
private static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject
        {
            do
            {
                if (current is T)
                {
                    return (T)current;
                }
                current = VisualTreeHelper.GetParent(current);
            }
            while (current != null);
            return null;
        }

Sorry, hab ich vergessen.

Versuch fremden Code nicht einfach zu kopieren sondern schreib ihn besser ab, dann fallen Fehler schon etwas füher auf.

Damit hast du natürlich recht. Problem ist, dass ich nicht weiß, was für Drag&Drop zu implementieren ist, damit kann ich es auch nicht verbessern. Ich finde nicht wirklich was dazu, außer das hier: Klick
... wobei ich auch daraus die erforderliche Logik für Drag&Drop nicht entnehmen kann.

Zur Vervollständigung:

 private void DragListView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            startPoint = e.GetPosition(null);

        }

        private void DragListView_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            // Get the current mouse position
            Point mousePos = e.GetPosition(null);
            Vector diff = startPoint - mousePos;

            if (e.LeftButton == MouseButtonState.Pressed &&
                (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
                Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
            {
                // Get the dragged ListViewItem
                ListView listView = sender as ListView;
                ListViewItem listViewItem =
                    FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);

                // Find the data behind the ListViewItem
                Contact contact = (Contact)listView.ItemContainerGenerator.
                    ItemFromContainer(listViewItem);

                // Initialize the drag & drop operation
                DataObject dragData = new DataObject("myFormat", contact);
                DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Move);
            }
        }

        private static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject
        {
            do
            {
                if (current is T)
                {
                    return (T)current;
                }
                current = VisualTreeHelper.GetParent(current);
            }
            while (current != null);
            return null;
        }

        private void DragListView_DragEnter(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent("myFormat") || sender == e.Source)
            {
                e.Effects = DragDropEffects.None;
            }
        }

        private void DragListView_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("myFormat"))
            {
                Contact contact = e.Data.GetData("myFormat") as Contact;
                /*ListView listView = sender as ListView;
                listView.Items.Add(contact);*/
                _Liste.Add(contact);
            }
        }

/EDIT: Komischer Weise tritt die ArgumentNullException nur sporadisch auf. Ansonsten "Klappt" die D&D - Operation Augenscheinlich, außer, dass das Item kopiert und nicht ersetzt wird. Dafür dürfte wohl

/*ListView listView = sender as ListView;
                listView.Items.Add(contact);*/
                _Liste.Add(contact);

sorgen. Die ersten beiden Varianten sind vom geposteten Tutorial, die Variante über die ObservableCollection wurde von mir geschrieben, da listView.Items.Add nicht kompiliert wird.

30.08.2017 - 15:41 Uhr

Danke für die Antwort, mit dem Tutorial hatte ich es auch bereits probiert.

Wenn ich den Sourcecode so kopiere, wie er dort erwähnt wird, kriege ich direkt eine ArgumentNullException an der Stelle:

ListViewItem listViewItem =
                    FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);

                // Find the data behind the ListViewItem
                Contact contact = (Contact)listView.ItemContainerGenerator.
                    ItemFromContainer(listViewItem);

listViewItem ist null, demnach funktioniert die Methode FindAnchestor nicht wie sie es soll...

Mir erschließt sich der Sinn dieses Aufrufes aber auch nicht:

ListViewItem listViewItem =
                    FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);
27.08.2017 - 12:34 Uhr

Hi,

ich wollte ein paar Sachen mit Drag&Drop ausprobieren. Dafür wollte ich eigentlich die Events MouseMove, MouseLeftButtonDown und DragOver verwenden.

Nun schon zum ersten Problem: Das MouseLeftButtonDown-Event wird nur dann aufgerufen, wenn man auf einen leeren Bereich innerhalb der ListView klickt. Wenn man auf ein Item klickt (Was man fürs verschieben ja zwingend machen muss), wird es nicht aufgerufen.

Laut der Dokumentation sollte es jedoch eig. aufgerufen werden, oder?

Occurs when the left mouse button is pressed while the mouse pointer is over this element.

Oder verstehe ich das falsch?
LG

23.08.2017 - 22:30 Uhr

Eine StaticResource ist nicht notwendig. Die Controls erben alle den DataContext vom Window. Du verwendest für dein Vorhaben also ein normales Binding.

Grrrr... Danke für die Antwort, ich hätte schwören können, dass ich das Probiert habe und einen Compiler-Fehler hatte... Hab also anscheinend doch irgendwas trotz x-maliger Überprüfung übersehen. Gut. Hatte mich eh gewundert, dass das nicht klappte.

Bisher läuft das mit den Bindings soweit super, ich bin immer mehr davon begeistert, wie einfach es doch im Endeffekt ist!

Ich habe vorhin auch den Beispiel-Converter benutzt, um die Bindings zu debuggen.
Und genau da bin ich jetzt:

  1. ListView klappt, dem DataContext wird ein Objekt vom Typ
System.Windows.Data.ListCollectionView

übergeben und im GridView dann an eine Eigenschaft mit dem Bezeichner "Name" gebunden. Klappt.

Nun ein 2. ListView, auch dort erhalte ich mittels Converter als value ein Object von oben genannten Typ - jedoch ist die ListView leider leer. Value enthält auch die richtige Anzahl an Objekten (In meinem Fall heißen die "SubjectModel" mit der einzigen Eigenschaft Name, die auch richtig initialisiert wird) und der Zeiger "CurrentItem" zeigt auf das erste Objekt. Scheint also von der Datenlage her richtig zu sein. Nun der Code:

<ListView Grid.Row="2" Name="ScheduleListView" DataContext="{Binding ScheduleCollectionView, Converter={StaticResource DebugConverter}}">
                <ListView.View>
                    <GridView>
                        <GridViewColumn DisplayMemberBinding="{Binding Name,Converter={StaticResource DebugConverter}}" Header="Mein Name" />
                    </GridView>
                </ListView.View>

Ich erhalte keinen Fehler in der Ausgabe und der Converter wird auch nur beim ListView - Binding aufgerufen, komischer Weise jedoch nicht beim DisplayMemberBinding der GridView...

Ferner habe ich auch schon probiert, die ObserveableCollection einfach nur mit Strings zu befüllen - klappt auch nicht.

Jemand eine Idee?
Danke & LG

23.08.2017 - 18:03 Uhr

OK, dann werde ich es jetzt so machen, dass alle ViewModels's im Code erzeugt werden - finde ich auch besser.

Nun habe ich ebenfalls mittels

protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            MainWindow w = new MainWindow();
            _MainViewModel = new MainViewModel();
            w.DataContext = _MainViewModel;
            w.Show();
        }

Dem Window.DataContext eine Instanz des MainViewModel's übergeben. Nun die wichtige Frage ( Ich bin jetzt an einer x-beliebigen Stelle, wo ich vorher über XAML die Instanz erstellt hätte):

Über DataContext hätte ich jetzt einem Sub-Control sein ViewModel zugewiesen.. Mittels StaticResources. Ich muss nun also hergehen und sagen, dass der DataContext des ListViews nicht

Window.DataContext

ist sondern

Window.DataContext.MeineEigenschaft

, wobei MeineEigenschaft z.B. Ein SubViewModel, welches im MainViewModel erzeugt wurde. Mittels ItemsSource könnte ich dann zb. an Eigenschaften von SubViewModel binden... Verstehst du was ich meine?

Ich muss also sagen, dass der DataContext meines Sub-Controls eine Eigenschaft, also ein Path, des Objektes ist, das an den DataContext des Windows übergeben wurde.

MfG

23.08.2017 - 08:44 Uhr

OK, das war auch meine Überlegung, also per DataContext zuweisen.

Das geht im MainWindow auch mit this.DataContext recht einfach... Im ViewModel, welches nicht von Window abgeleitet ist, klappt das m.W.n. nicht, richtig?

Ich kann also über Application.current.MainWindow gehen... Aber das kann ich dann ja nur für ein ViewModel machen und nicht mehrere... Muss ich mich dann durch die Einzelnen Elemente hangeln, nur um dem richtigen dann die Instanz per DataContext zuzuweisen?

MfG

22.08.2017 - 17:28 Uhr

Hallo, ich habe folgendes Problem und habe beim googlen nichts finden können, da anscheinend der andere Weg gefragter ist...

Also, ich habe ein ViewModel, welches verschiedene Instanzen von anderen ViewModels enthält.

In einer ListView wird an eine gemeinsame Eigenschaft gebunden und bei der Auswahl eines der Objekte wird der angebundene ContentControl automatisch geladen und angezeigt.

Ich habe nun folgendes Problem: Im Konstruktor des 1. ViewModels wird eine Instanz erzeugt, welche in eine ObservableCollection<> kommt und im ListView angezeigt wird.
Wenn was ausgewählt wird, kommt nun der ContentControl zum Einsatz. Bisher habe ich bei aber immer nur im XAML eine Instanz mit

<ns:MeineKlasse x:key="vm"/>

machen können. Im folgenden Fall würde ich dann ja mit 2 verschiedenen Instanzen arbeiten, einmal die, die im 1. VM erzeugt wird und dann die, die im ResourcenWörterbuch erstellt wird.

Wie gehe ich vor? Gibt es was ähnliches wie TryFindResource? Im Prinzip müsste ich im DataContext anstelle von

{StaticResource meinVM}

auf die Instanz irgendeiner Klasse verweisen...

Danke

20.08.2017 - 18:49 Uhr

Übrigens etwas, was mir in meiner Zeit mit VS nun aufgefallen ist:

Öfters habe ich Fehler im XAML-Code (z.B. findet er Klassen in Namespaces nicht etc.)...

Wenn ich Neustarte kann das das Problem beheben, anderenfalls reicht ein klick auf "Run" und der Fehler löst sich in Luft auf.

(Natürlich nur, wenn auch alles richtig ist.)

Ist für einen Anfänger wie mich sehr ärgerlich, weil man nicht immer sich ja nicht immer sicher ist mit der richtigen Ausführung mancher Befehle...

19.08.2017 - 11:43 Uhr

Puh, ehrlich gesagt glaube ich nicht...

Vielleicht kannst du ja mal bei Gelegenheit drauf schauen?

Danke 😃

18.08.2017 - 17:45 Uhr

Leider hat es damit schonmal nicht funktioniert 😕

Also das Timer-Event wird aufgerufen,
CommandManager.InvalidateRequerySuggested();
demnach auch, aber es ändert sich nicht.

Ehrlich gesagt verwundert mich dieses Verhalten... Ich dachte Bindings in Zusammenhang mit INotifyPropertyChanged wäre genau dafür da, dass sich die GUI updatet?

Achja, ist das ICommand - Verhalten normal, dass die Ausführung so lange dauert?

17.08.2017 - 19:13 Uhr

Danke, hat soweit alles geklappt.

Habe aber dennoch 2 kleine Fragen:

  1. Habe spaßeshalber paar Buttons mit Commands den jeweiligen ViewModels zugewiesen. Die Methoden werden auch aufgerufen. In der Methode steht zb. ein einfaches Console.WriteLine().
    Dieses wird aber, warum auch immer, erst ne halbe Sekunde o.ä. aufgerufen, sodass man den Knopf 3 mal drücken kann, bis man was sieht. Das kommt sehr träge rüber... Liegt das an der Konsolenausgabe oder an dem Command?

  2. Habe im 2. ViewModel ebenfalls einen Button. In der CanExecute gebe ich eine bool-Variable zurück, die mittels Timer erst nach 5 Sekunden auf true gesetzt wird. INotifyPropertyChanged ist implementiert (In der Base-Class). Komischer Weise bleibt der Button deaktiviert, bis ich entweder in den beiden Listeneinträgen hin und dann wieder zurück wechsle (was absolut logisch ist), oder jedoch,wenn ich irgendwo auf das Fenster klicke (Für mich weitaus weniger logisch).

Die Variable (bool) MyButtonActive wird im Timer_Elapsed - Handler geändert... kann das was damit zu tun haben?

Danke und MfG
Robin

16.08.2017 - 17:39 Uhr

Danke für die Antwort, ich bin jetzt ein großes Stück weiter, mit

<ContentControl Grid.Row="2" Content="{Binding SelectedItem, ElementName=lstView}" >
                <ContentControl.Resources>
                    <DataTemplate  DataType="{x:Type s:SecondPageViewModel}">
                        <Button >Mein2.Button insourced</Button>

                    </DataTemplate>

                    <DataTemplate  DataType="{x:Type s:GeneralSettingsViewModel}">
                        <Button >Mein1.Button insourced</Button>

                    </DataTemplate>
                </ContentControl.Resources>
            </ContentControl>

Habe ich schonmal das DataTemplate vom entsprechend ausgewählten ViewModel als Content!

Nun bin ich gerade dabei, die DataTemplates in die Window.Resources auszulagern, um sie im nächsten Schritt sogar in ein ResourcesDictionary auszulagern.

Also:

 <Window.Resources>
        <s:DataBindingDebugConverter x:Key="debugConverter"/>

        <DataTemplate x:Key="SecondPageViewModel" DataType="{x:Type s:SecondPageViewModel}">
            <Button >Mein2.Button - Outsourced</Button>

        </DataTemplate>

        <DataTemplate x:Key="GeneralSettingsViewModel" DataType="{x:Type s:GeneralSettingsViewModel}">
            <Button >Mein1.Button - Oursourced</Button>

        </DataTemplate>

    </Window.Resources>

Und nun zum Code, der Leider nicht die Button anzeigt, sondern, ich schätze mal, den string der Methode ToString().

 <ContentControl Grid.Row="1"  Content="{Binding SelectedItem, ElementName=lstView}" ContentTemplate="{Binding SelectedItem.Name, ElementName=lstView}">
                

            </ContentControl>

Ich weiß, dass das Binding vom ContentTemplate keinen Sinn macht, schließlich brauche ich nicht den ToString(), um das richtige DataTemplate auszuwählen sondern BaseSettingsViewModel.Name

Wie binde ich das richtig?
Danke

P.S.: Ich habe deinen DebugConverter mal angeschmissen (Siehe Anhang).
Es kommt als Value schonmal der richtige Name raus: "GeneralSettingsViewModel".
Target type: System.Windows.DataTemplate scheint mir ebenfalls korrekt.

Eigentlich stimmt das doch soweit, oder irre ich mich?
LG und Danke!

15.08.2017 - 17:51 Uhr

Sei mir nicht böse,
ich habe jetzt sowohl deinen Artikel als auch die Dokumentation durchstöbert, aber ich finde nirgends einen Hinweis darauf, was ich machen muss.

Klar, mit dem Snipped

 <ItemsControl Grid.Row="1">
                <ItemsControl.Resources>
                    <DataTemplate x:Key="Key?">
                        <StackPanel Orientation="Horizontal">
                            <Label Content="Text" />
                            <Label Content="Text2" />
                        </StackPanel>
                    </DataTemplate>
                    
                </ItemsControl.Resources>
            </ItemsControl>

Setzt man einen ItemsControl mit einem DataTemplate. Das DataTemplate könnte man nun bestimmt auslagern in eine andere Resource-Datei. Ok.

Aber wie und vor allem an was soll ich das Binden? Wie gesagt wird mir das nicht klar, weder aus der Doku noch aus deinem Artikel und bei einer generellen Suche habe ich auhc nichts gefunden (Was vielleicht auch daran liegen mag, dass ich nicht weiß, wonach ich da eigentlich suche?).

Danke.

14.08.2017 - 20:11 Uhr

Ich würde das wahrscheinlich mit DataTemplates umsetzen. Diese kannst du im der MainView oder in eigenen XAML-Dateien erstellen. Dann wird je nach Typ des links ausgewählten ViewModels rechts die im entsprechenden Template definierten Controls angezeigt:

  
<DataTemplate DataType="{x:Type GeneralSettingsViewModel}">  
    <!-- Controls for General Settings Page -->  
</DataTemplate>  
  

Könntest du mir noch ein paar Anhaltspunkte geben? Habe paar Sachen ausprobiert, komme aber leider nicht weiter, bzw. weiß ich nicht wirklich, womit ich Anfangen soll...

Folgendes: MainViewModel, welches eine ListCollectionView hält. Diese ist mit einer ObservableCollection<string> initialisiert und wird an die ListView gebunden --> zum probieren, es klappt schonmal.

Nun muss ich eine SettingsViewModel schreiben , die ObservableCollection zu <SettingsViewModel> ändern, und dann die Collection mit verschiedenen SettingsViewModel-Objekten füllen?

Wie verbinde ich nun diese Objekte 1. mit dem DataTemplate aus dem ResourcenWörterbuch und 2. wie binde ich dann DataTemplate des ausgewählten Elements an "ein Objekt" in der MainWindow, um es anzuzeigen?

Hoffe, dass mein Ansatz zumindest nicht ganz falsch ist.
Danke

P.S: Beim DataTemplate definiert man ja auch einen DataType... braucht man dafür dann nicht verschiedene Instanzen verschiedener Objekte, oder wie funktioniert die "Verknüpfung" zwischen SettingsViewModel-Instanz und dem DataTemplate?

11.08.2017 - 18:14 Uhr

Bei deinem angehängten DropBox Projekt hast du das falsche Nuget Package installiert. Das ist bei mir auch nicht lauffähig. Das Nuget Package ist übrigens auch nicht von Microsoft veröffentlicht worden.

Wenn du das Nuget Package "Expression.Blend.Sdk" von Microsoft installierst, geht es.

Danke, du hattest Recht, in dem kleinen Projekt hatte ich es hinbekommen.

Es gehört vielleicht nicht mehr zum Thema, aber was hat man falsch gemacht, wenn die InitializeComponents() als Fehler angezeigt wird? Ich habe beim googlen rausbekommen, dass es evt. damit zusammen hängt, dass man verschiedene Namespaces in der XAML/ Codebehind angibt - das ist nicht der Fall... Eine Idee?

Projekt

Danke!

//EDIT: Ich weiß nicht warum, aber das Problem hat sich in Luft aufgelöst. Ist mir jetzt schon öfters passiert, dass Probleme sich nach mehrmaligem neustarten von Visual selbst fixen... ist das normal?

10.08.2017 - 18:42 Uhr

Danke für dein TestProjekt - kannst du das kompilieren? Ich nämlich nicht. Die Packages sind installiert (Siehe Bild), aber er findet wieder namespaces nicht 😕 Verstehe ich nicht 😦

Ich habe jetzt ein neues Projekt gemacht (Klick). In diesem habe ich über die NuGet - GUI probiert die Interactivity.dll hinzuzufügen. Hat auch geklappt, dachte ich.

Er erkennt den Namespace und auch die Tags wie i:Interaction.Triggers (schonmal ein Fortschritt) nur leider gibt es trotzdem noch Fehler...

An dieser Stelle ist das Buch echt nicht gut beschrieben... Ich vermute, dass es ein paar Kleinigkeiten sind, die ich bisher nicht verstanden habe... Vielleicht magst du mal drüber schauen?

Danke!

P.S: Sorry für den Dropbox-Link, die Zip von dem Projekt ist über der maximalen Uploadhöhe:/

09.08.2017 - 21:20 Uhr

Ich habe die Frage so verstanden, dass es darum geht komplette "Views" nach einem Navigation Item click zu laden.

Genau das war meine Frage... Ich habe mich nun etwas mit MVVM beschäftigt. Aber nochmal zur anfänglichen Frage: Würde man das abgebildete Fenster ausschließlich mit einer XAML-Datei aufbauen (+ 1 ViewModel) und alles x-Tausend Elemente hiden, abhängig vom ausgewählten Item? kann ich mir nicht vorstellen.

Also ContentControl als Container, dieser kriegt dann mit Bindings ein "UserContentControl" (schätze mal eine eigene Klasse?) zugewiesen?

Jeder UserContentControl also wieder eine XAML, nur ohne Window - Definition, und mit eigenem ViewModel?

Danke für meine Verständnishilfe!

MfG Robin

09.08.2017 - 17:11 Uhr

Danke Palladin007, damit kriege ich schon Mal den Compiler-Fehler beim bekanntgeben der URI weg:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

Leider treten noch weitere Fehler an folgender Stelle auf:

<TextBox Text="{Binding PersonDetails, UpdateSourceTrigger=PropertyChanged}" Name="txtDetailInformation" Grid.Row="1" TextWrapping="Wrap" >
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseEnter">
                            <i:InvokeCommandAction Command="{Binding MouseEnterCommand}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </TextBox>

Fehler:

Der Name "Interaction" ist im namespace xxx nicht vorhanden.

Nun zu den Fragen von Abt:
Ich habe das Buch C#6 mit Visual Studio 2015 - schien mir beim Kauf nicht soooo alt..

Ich habe einer Anleitung von der NuGet-Seite... Dort habe ich mit

Install-Package Expression.Blend.Sdk -Version 1.0.2

in der Nuget-Console versucht, das Package hinzuzufügen - was auch klappte.

Hast du vielleicht eine bessere Alternative, auf das Event im ViewModel zu reagieren? (Ohne Code in der XAML-Code-behind).

Danke.
MfG Robin

08.08.2017 - 17:50 Uhr

Hallo,

Ich bin gerade dabei, ein Beispiel bzg. MVVM nachzubauen. Dort geht es gerade um EventTrigger-Objekte aus der Interactivity.dll - Erweiterung.

Ich kriege leider einen dicken Fehler, beim Versuch, den CLR-Namespace der Erweiterung bekannt zu geben:> Fehlermeldung:

Der URI "clr-namespace:System.Windows.Interactivity; assembly=System.Windows.Interactivity" ist keine gültige Namespace-ID

Wie zu sehen, habe ich die Lib referenzieren können (Siehe Bild), kriege den Fehler jedoch bei folgendem XAML-Code:

 xmlns:i="clr-namespace:System.Windows.Interactivity; assembly=System.Windows.Interactivity"

Nun meine Frage: Was mache ich falsch?

Danke schnmal,
MfG Robin

26.07.2017 - 21:11 Uhr

Hi, glaube ich muss noch viel lesen, bin erst neu dabei 😃

Ich habe die Frage so verstanden, dass es darum geht komplette "Views" nach einem Navigation Item click zu laden

Ehrlich gesagt dachte ich, dass das der sinnvollste weg wäre, um nicht alles in einer Klasse zu haben.
Ich habe gerade mal angefangen den Artikel über das MVVM-Entwurfsmuster zu lesen, allerdings kann ich an zu vielen Stellen nicht folgen, z.B. schon direkt am Anfang 😄

  readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;  

Ich werde mir das zu Gemüte führen und mich dann wieder mit konkreten Fragen melden!

Danke und Grüße

26.07.2017 - 16:33 Uhr

Hallo Leute.

Also, ich hab jetzt schon länger danach gesucht und probiert, aber leider keine Antwort finden können.

Wie realisiert man so ein Fenster (Siehe Anhang)? Klar, ListView für die Einträge, aber wie macht man es am geschicktesten, dass sich, je nach Eintrag, die Inhalte anpassen?

Danke 😃