Forum: PC-Programmierung First Floor - modern Ui


von Johannes (Gast)


Lesenswert?

Hallo,
ich möchte mir mit C# ein Tool erstellen. Dazu habe ich mir von 
FirstFloor die Modern UI besorgt. Sieht ja auch ganz nett aus. Ein 
großer Nachteil (für mich) ist, dass sich die Buttons zu den 
verschiedenen Menüs an der oberen Seite befinden. Ist es irgendwie 
möglich, diese an der Seite (untereinander) zu bekommen, oder wenigstens 
kein Untermenü mehr machen zu müssen? Oder kennt jemand eine andere 
Vorlage, wo das so ist?

Gruß

Johannes

von Johannes (Gast)


Lesenswert?

https://github.com/firstfloorsoftware/mui
Mit Menu und Untermenu meinte ich z.B. Welcome (Menu) Introduction 
(Untermenu)

von Rene K. (xdraconix)


Lesenswert?

Ich wundere mich ja, aber warum machst du dir da nicht einfach ein 
Label, feste Höhe und Breite, Schrift einstellen, dann "klickable" und 
Wertest es damit aus?

von Bernd K. (prof7bit)


Lesenswert?

Ich hasse es wenn Anwendungen nicht das native Look & Feel der 
Desktopoberfläche verwenden sondern versuchen das Rad neu (und 
unvollständig) zu erfinden. Sie verhalten sich subtil anders, sie 
verwenden die falschen Farben, sie wirken wie ein Fremdkörper und 
verursachen nur Probleme.

von Mareike (Gast)


Lesenswert?

Hallo Johannes und alle anderen.
Bei mir auf der Arbeit hat auch jemand eine Software mit modern ui in 
wpf erstellt. Das sah sehr gut aus und daher wollte ich mir jetzt zu 
hause auch eine software erstellen.
Jeder Teil der Software ist ja in drei Bereiche unterteil (Model, 
Viewmodel und View). Wozu die da sind ist mir klar
Model ist der eigentliche Code, Viewmodel ist die Verbindung vom Model 
und der Gui und in View ist die Gui enthalten. Aber ich begreiffe nicht, 
wie das funktioniert. Hast du zufällig ein einfaches Beispiel, wo man 
den Signalverlauf noch einmal genau sehen kann und vor allem, was ich 
machen muss?

Zunächst habe ich eine einfache View erstellt, wo man seinen NAmen und 
Geburtsdatum eingeben kann. Beim speichern auf einen Button, soll der 
Name und das Geburtsdatum dann in eine XML geschrieben werden (das wird 
dann ja im Model gemacht). Aber wie bekomme ich jetzt, dass wenn ich den 
Button drücke, sich das Speicherfenster öffnet?

Hoffe, mir kann einer Helfen. Habe schon den ganzen NAchmittag nach 
Tutorials gesucht, wo dieser Ablauf einmal komplett gemacht wird, aber 
leider nichts brauchbares (also das ich das verstanden habe) gefunden.

liebe grüße

Mareike

von Johannes (Gast)


Lesenswert?

Da gibt es eigentlich viele youtube-videos. Aber da es bei mir auch noch 
nicht funktioniert, kann ich auch leider kein beispiel geben.

Daher die Frage an alle anderen.
In meiner View habe ich einen Button mit
1
        <Label Grid.Row="1" Grid.Column="1" FontWeight="SemiBold" Content="Name" HorizontalAlignment="Left" VerticalAlignment="Top" />
2
        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding InputUserName}" />
3
4
        <Label Grid.Row="3" Grid.Column="1" />
5
6
        <Label Grid.Row="4" Grid.Column="1" FontWeight="SemiBold" Content="Geburtstag" HorizontalAlignment="Left" VerticalAlignment="Top" />
7
        <TextBox Grid.Row="5" Grid.Column="1" Text="{Binding InputUserBirthday}" />
8
9
        <Label Grid.Row="6" Grid.Column="1" />
10
        <Button Grid.Row="9" Grid.Column="1" Content="Benutzer speichern" Command="{Binding SaveUserDataCmd}"/>

mein ViewModel sieht wie folgt aus
1
using System.Windows;
2
3
using MySport.Helpers;
4
using MySport.Pages.Home.NewUser.Models;
5
6
namespace MySport.Pages.Home.NewUser.ViewModels
7
{
8
    public class NewUserViewModel : ViewModelBase
9
    {
10
        private NewUserModel _newUserModel;
11
        public RelayCommand SaveUserDataCmd { get; private set; }
12
13
        public NewUserViewModel()
14
        {
15
            _newUserModel = new NewUserModel();
16
            SaveUserDataCmd = new RelayCommand(SaveUserData);
17
        }
18
19
20
        private void SaveUserData(object obj)
21
        {
22
            MessageBox.Show("test");
23
            _newUserModel.SaveUser();
24
        }
25
    }
26
}

Für das ViewModelBase habe ich eine Helpers
1
namespace MySport.Helpers
2
{
3
    public class BaseViewModel : INotifyPropertyChanged
4
    {
5
        public event PropertyChangedEventHandler PropertyChanged;
6
        protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
7
        {
8
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
9
        }
10
    }
11
}



und mein Model:
1
using System.Xml;
2
3
namespace MySport.Pages.Home.NewUser.Models
4
{
5
    public class NewUserModel
6
    {
7
8
        string _userName;
9
        string _userBirthday;
10
11
12
        public NewUserModel()
13
        {
14
15
        }
16
17
        public void SaveUser()
18
        {
19
            using (XmlWriter writer = XmlWriter.Create("MySportUsers.xml"))
20
            {
21
                writer.WriteStartDocument();
22
                writer.WriteStartElement("Users");
23
24
                writer.WriteStartElement("User");
25
                writer.WriteElementString("Name", UserName);
26
                writer.WriteElementString("Birthday", UserBirthday);
27
28
                writer.WriteEndElement();
29
                writer.WriteEndDocument();
30
            }
31
32
        }
33
34
        public string UserName
35
        {
36
            get { return _userName; }
37
            set { _userName = value; }
38
        }
39
40
        public string UserBirthday
41
        {
42
            get { return _userBirthday; }
43
            set { _userBirthday = value; }
44
        }
45
46
    }
47
}

eigentlich sollte beim drücken des Buttons ein fenster geöffnet werden 
(nur da das eintragen in die xml nicht unbedingt funktionieren muss) und 
ein Eintrag in eine xml angelegt werden. Aber nichts passiert.
Selbst wenn ich in der Funktion SaveUserData einen Brakepoint setze, 
sehe ich, dass diese Funktion erst gar nicht aufgerufen wird.


Kann mir da jemand helfen?

Johannes

von Bärbeiß (Gast)


Lesenswert?

Johannes schrieb:
> Selbst wenn ich in der Funktion SaveUserData einen Brakepoint setze,
> sehe ich, dass diese Funktion erst gar nicht aufgerufen wird.

Ich sehe nirgendwo die Erzeugung einer Instanz des ViewModels und die 
DataContext-Zuweisung.

Falls du das übersehen hast (der View-Code steht oben ja nicht), 
schreibe mal

DataContext = new NewUserViewModel();

in den Konstruktor der View.
http://paulstovell.com/blog/mvvm-instantiation-approaches

>> MessageBox.Show("test");

Eigentlich sollte im View-Model nichts stehen, was direkt auf 
UI-Komponenten zugreift (u.a., weil sich das VM dann nicht mehr so 
einfach testen lässt). Man kann stattdessen z.B. eine eigene 
Service-Klasse für Messageboxen, Open/Save-Dialoge etc. schreiben und 
dann im VM mit einem Interface arbeiten.
Andererseits würde ich es bei einem kleinen Programm mit der "Strenge" 
nicht übertreiben. Bei einem wirklich kleinen Tool (im Sinne der 
Komplexität) würde ich vermutlich nicht einmal das MVVM-Pattern 
einsetzen, sondern ganz einfach und altmodisch Messagehandler (die 
eigentliche Funktionalität aber immer in eigenen Klassen oder Assemblys 
implementieren, nie in GUI-Klassen).

Was mir gerade noch auffällt:
Da steht zwar

>> public RelayCommand SaveUserDataCmd { get; private set; }

aber das tut ja nichts weiter.
Du musst die Verbindung zwischen Command und Methode selbst herstellen. 
So in der Art (es kommt natürlich auf die RelayCommand-Implementierung 
an, die du benutzt):
1
// VM
2
3
public bool CanSave => true; // Zum Ausprobieren
4
5
private RelayCommand _saveCommand;
6
public ICommand SaveCommand
7
{
8
  get
9
  {
10
    if (_saveCommand == null)
11
    {
12
      _saveCommand = new RelayCommand(param => this.SaveUserData(),
13
        param => this.CanSave);
14
    }
15
    return _saveCommand;
16
  }
17
}
18
19
private void SaveUserData()
20
{
21
  MessageBox.Show("test");
22
  _newUserModel.SaveUser();
23
}
1
<Button Grid.Row="9" Grid.Column="1" Content="Benutzer speichern" Command="{Binding SaveCommand}"/>

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.