Hallo,
ich möchte Pushbenachrichtigungen an alle App User schicken können (Ähnlich wie Firebase) nur ohne dafür zu zahlen.
In Android erstelle ich dafür einen Foreground Service. Dieser Pollt ständig einen server und wenn eine neue Benachrichtigung vorhanden ist, dann wird diese per push benachrichtigung an den User gesendet.
Ich greife quasi mit einem Restzugriff auf eine Api und diese Liest dann die in einer Datenbank abgelegten Notifications aus (GET Zugriff). Gibt es eine bessere Möglichkeit?
In IOS klappt das irgendwie nicht oder ich finde da keine Richtige Dokumentation, wie ich dasselbe im Hintergrund machen könnte.
Habt ihr da eine Idee?
Also erstmal danke ich nochmal allen. Das hat mir echt weitergeholfen.
Ich habe jetzt das mit den MultiViewmodels verstanden, aber nutze doch die Messenger, weil die echt praktisch sind.
Jetzt entwickle ich alle Viewmodels unabhängig voneinander und kommuniziere bei Bedarf mit Messengern.
Jetzt habe ich eigentlcih aus dem allen nur noch 2 Fragen, die mir etwas Unklarheit geschaffen haben.
Diese Dinger unterscheiden sich zu DB und Dateien Zugriff darin, dass mit einem externen Partner kommuniziert wird, also gehört das nun zur Business Logic oder zu dem Data Access Layer?
2. Ich nutze den DI Container von Microsoft für alle ViewModels und diverse Singleton Klassen aus der Business Logic, damit diese in der GUI Schicht zur Verfügung stehen. Aber kleine Klassen, die nur innerhalb einer Klasse verwendet werden, erstelle ich immernoch mit new. Ist das eher gegen das Konzept? Sollte jedes Object mit dem DI erstellt werden?
Hallo Alf,
erstmal danke dir für deine Zeit.
Ich habe mir jetzt verschiedenste Dinge angesehen und mir alle Beiträge durchgelesen (nicht alles im Detail verstanden), aber ich glaube, dass die Messenger genau das sind, was ich suche. Nichtsdestotrotz sollte es doch auch ohne gehen oder´? Ich glaube, dass deine Lösung immer noch nicht mein Anliegen löst. Daher habe ich ein weiteres Beispiel. Mit dieser Problemstellung kann ich einfach kein DI nutzen. Mit new würde es klappen, daher habe ich das Ziel Projekt ohne DI und ein unfertiges Wunschprojekt mit DI angehangen.
Also ganz kleines WPF Projekt mit 4 Grid Zeilen im MainWindow Fenster - gebunden an MainWindowViewModel:
Zeile 0: TextBlock mit Hintergrund farbe (Rot oder Grün)
Zeile 1: ListView (Gebunden an LiestViewItems property in ListViewViewModel mit UserControl ListView)
Zeile 2: Eingabe TextBox: Inhalt gebunden an TextBoxContent property im MainWindowViewModel
Zeile 3: Add und DeleteButton beide gebunden an jeweils 1 buttonCommand im MainWindowViewModel. Beide Commands manipulieren LiestViewItems property aus dem UserControl (Bis hierhin klappt es mit dem MultiViewModel). Sobald LiestViewItems property mehr als 5 Elemente hat, wird das TextBlock aus Zeile 0 (gebunden auf property im MainWindowViewModel) rot.
Mit new klappt auch das, weil ich ja beim erstellen von ListViewViewModel auch die Referenz mit This MainWindowViewModel übergeben kann. Aber mit dem DI kriege ich das nicht hin. Hat da einer eine Idee?
Zitat von Alf Ator
Du könntest ein Haupt-ViewModel benutzen, dass die anderen ViewModels hält und mit Daten füttert.
Ich habe dir mal ein minimales Beispiel angehängt.
Ich hatte jetzt doch lust etwas wenig zu schlafen und mich daran zu setzen^^ Dein Beispiel ist doch dahingegen anders als mein Fall, da ich mehrere Views habe, es ist ähnlich zu dem Fall bei dem Verlinkten anderen Beitrag.
Ich sehe mir das mit den Messengern mal an, aber ich verstehe die Aufteilung von MVVM wohl nicht 100%. Daher mal ein anderes Beispiel. Ich habe ein Projekt, da möchte ich in der View editierbare Textboxen haben. Der Inhalt der Textboxen stammt defaultmäßig aus xml dateien und kann in der View beschrieben und in die xml Datei geladen werden. Die Textboxen enthalten lediglich Zahlen. Die View zeigt zu den Zahlen einen Text. Text zu Zahl die Information stammt aus einer DB.
Jetzt frage ich mich ok, Text zu Zahl aus der DB ist Teil des Models/Businessmodels, Laden des Inhalts der Zahlen aus einer Datei und Speichern in eine Datei auch auch? Was passiert dann im ViewModel, werden dort nur die Klassen DB und File laden als Objekte erstellt und die Methoden genutzt + Button Commands und Alle Binding Variablen? Versuche ich soviel in Modell zu legen, wie geht? Die Methoden des Modells spucken als return values dann strings oder listen aus und diese werden im Viewmodell an die Binding variablen übergeben?
Sehe ich das so korrekt?
Danke an alle, dass muss ich mir am Wochenende mal im Detail ansehen.
Wenn die Oberservable Collection in dem ViewModel bleibt, was mache ich dann in dem eben beschriebenen Fall der 3 ViewModels?
ViewModel 1 Enthält die observable Collection, des Listviews, aber in ViewModel 2 und 3 (Für Bereiche 2 & 3) sind Controls, die diese ListView ändern. Soll und womöglich gibt es in Bereich 1 auch Elemente, die Inhalte von Bereich 2 und 3 ändern. Dann müsste ich Referenzen hin und her geben und habe diese circular dependency. Mit dem exportieren der observable Collection und aller weiteren Bindings der 3 ViewModels, kann ich von den 3 ViewModels aus jedes gebundene GUI Element verändern.
Wie würde man das denn anders implementieren?
Erstmal Danke für die ganzen Nachrichten
Also wenn ich das richtig verstehe...
Ich habe 3 Bereiche in der GUI. Bereich 1 enthält eine ListView. Bereich 2 enthält UI Elemente, die die ListView mit Inhalt füllen. Bereich 3 Enthält ebenfalls UI Elemente, die die Listview ergänzend mit anderem Inhalt füllen können oder komplett ersetzen können.
Es wird ein Service erstellt also zB. ListViewService, der gewisse methoden hat, die eine ListView mit dem jeweiligen Inhalt befüllen. In dem Service soll nicht die observable Collection enthalten sein. Die soll jedesmal im ViewModel aus der Liste erstellt werden? Aber so klappt das irgendwie nicht, denn, wenn die View aus Bereich 1 nur mit einer observable Collection aus dem Viewmodel 1 gebunden ist und ich in Bereich 2 ListViewService aufrufe und dort lokale Variablen ändere, merkt die View das nicht.
Daher hatte ich jetzt gedacht, dass der ListViewService die observable Collection enthält und in Bereich 1, 2 und 3 muss dieser Service nur noch injecten werden. An die View 1 aus Bereich 1 (UserControl) ist die observable Collection aus dem ListViewService gebunden. Dann ist die Manipulation der ListView abgekapselt in einer Klasse und diese wird einseitig von den Viewmodels aufgerufen. Wenn ich in Viewmodel 1, 2 oder 3 die Methoden aus ListViewService aufrufe, dann wird die View immer angepasst.
Wäre das so sinnig?
Dann wäre meine Frage. Der ListviewService würde auch die Businesslogik enthalten. Aber die BusinessLogik sollte eigentlich nicht die observable Collection enthalten oder?
Hier bin ich etwas verwirrt.
Wäre es dann sinnvoll ein ViewModel, ein ListViewViewModelService und eine ListViewBusinseslogik zu erstellen?
Und die Klassen werden derartig injected:
ViewModel → ListViewViewModelService → ListViewBusinseslogik
Hallo,
ich möchte einen Code mit einem MainWindow, MainWindowViewmodel und einem UserService schreiben. In der View gibt es eine TextBox, ein Button und ein Itemcontrol.
<Window x:Class="InversionOfControl.MainWindow"
...>
<StackPanel Margin="20">
<TextBox Text="{Binding InputName}" Margin="5"></TextBox>
<Button Command="{Binding AddNameButton}" Margin="5">Next ViewModel</Button>
<ItemsControl MinHeight="100" ItemsSource="{Binding Usernames}" BorderBrush="Black" BorderThickness="1" Margin="5">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Window>
In der View kann ein Name eingetippt werden und mit einem Klick auf den Button, wird eine Methode von UserService aufgerufen, die den Namen in die ObservableCollection aus dem ViewModel speichert. Ja das geht auch ohne UserService, aber für meine eigentliche Anwendung brauche ich eine derartige Konstellation, also ein Command aus dem Viewmodel, öffnet eine Methode eines Servcie und dieser Service ändert properties im ViewModel. Oder auch ein Viewmodel wird von einem anderen ausgerufen, und das gleiche Beispiele (Hierbei ist das . Viewmodel für einen kleinen Bereich der View verantwortlich und wenn Controls in diesem Bereich genutzt werden, ändern sich auch andere Bereiche).
So wie ich es versuchen will, geht das mit "new", denn so kann ich Referenzen wild hin und her geben. Aber ich möchte etwas besser programmieren und die IoC mit DI anwenden. Aber ich glaube ich mache da prinizipiell was falsch. Daher habe ich dieselbe Methode jetzt zweimal implementiert, um von der "altbewerten" Programmierart auf die etwas modernere umzusteigen, aber ich kriege es irgendwie nicht hin (Ich erhalte immer eine Meldung: A circular dependency was detected)
Meine Klassen ohne DI:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
}
}
public class MainWindowViewModel : ObservableObject
{
public ObservableCollection<string> Usernames { get; private set; } = new ObservableCollection<string>();
public RelayCommand AddNameButton { get; set; }
private string _inputName;
public string InputName
{
get { return _inputName; }
set
{
_inputName = value;
OnPropertyChanged();
}
}
private UserService _userService = new UserService();
public MainWindowViewModel()
{
AddNameButton = new RelayCommand(() =>
{
_userService.GetUsers(this);
});
}
}
public ObservableCollection<string> Usernames { get; private set; } = new ObservableCollection<string>();
public void GetUsers(MainWindowViewModel mainWindowViewModel)
{
mainWindowViewModel.Usernames.Clear();
Usernames.Add(mainWindowViewModel.InputName);
foreach (var username in Usernames)
{
mainWindowViewModel.Usernames.Add(username);
}
}
}
Meine Klassen mit DI:
public App()
{
Ioc.Default.ConfigureServices(
new ServiceCollection()
.AddSingleton<MainWindow>()
.AddSingleton<MainWindowViewModel>()
.AddTransient<IUserService, UserService>()
.BuildServiceProvider() );
MainWindow mainWindow = Ioc.Default.GetRequiredService<MainWindow>();
mainWindow.Show();
}
public MainWindow(IUserService iUserService, MainWindowViewModel mainWindowViewModel)
{
InitializeComponent();
this.DataContext = mainWindowViewModel;
}
public ObservableCollection<string> Usernames { get; private set; } = new ObservableCollection<string>();
public RelayCommand AddNameButton { get; set; }
private string _inputName;
public string InputName
{
get { return _inputName; }
set
{
_inputName = value;
OnPropertyChanged();
}
}
public MainWindowViewModel(IUserService userService)
{
AddNameButton = new RelayCommand(() =>
{
userService.GetUsers();
});
}
}
public ObservableCollection<string> Usernames { get; private set; } = new ObservableCollection<string>();
MainWindowViewModel _mainWindowViewModel;
public UserService(MainWindowViewModel mainWindowViewModel)
{
_mainWindowViewModel = mainWindowViewModel;
}
public void GetUsers()
{
_mainWindowViewModel.Usernames.Clear();
Usernames.Add(_mainWindowViewModel.InputName);
foreach (var username in Usernames)
{
_mainWindowViewModel.Usernames.Add(username);
}
}
}
Hi,ich habe das Probiert. Ja der Expander überdeckt das Rechteck, aber die erste Spalte des Grids wird bei der Expansion des Expanders einfach breiter.
Eine ComboBox verhält sich beispielsweise nicht so. Sie hebt sich über das Grid hinweg. Da wäre meine Frage, ob ich das auch für einen Expander einstellen kann oder allgemein für UI Elemente.