So I have a WPF program in which I have a ViewModel and several windows. I usually add the DataContext for my ViewModel like this:
<Window.DataContext>
<local:PrintView x:Name="printerView"/>
</Window.DataContext>
But if I do it that way, I have the problem that multiple instances of the ViewModel are created, one instance for each window. Which means that if I change a property in one window, the same property of the other window doesn't change.
Now I had done it in such a way that I define it in App.xaml like this:
<Application.Resources>
<ResourceDictionary>
<local:PrintView x:Key="printView"/>
</ResourceDictionary>
</Application.Resources>
And address in each window like this:
DataContext="{StaticResource printView}"
But now the problem is that I want to create the whole thing without the App.Xaml. Does anyone have any idea how I can create the same result without App.xaml? As well as without libraries.
I'm working with .NET Framework 4.8
EDIT
I have now implemented the solution from @mm8. However, it still doesn't seem to work. Everything works in the Xaml part and I have access to the properties. However, there are problems in the code behind, namely when I select a value in a window and save it in the property:
And so save the selected value in the property:
SelectedItem="{Binding selected_printer, Mode=TwoWay}"
But I then want to access this changed value in the other window, whether like this:
var vm = (ViewModel)this.DataContext;
vm.selected_printer
or like this:
ApplicationService.Instance.PrintView.selected_printer
No matter how I try to access the previously changed property in the other window, the property doesn't update in the other window with the new value.
So this value: SecondWindow is not transferred to the other window and is not updated
My Selected Printer defined:
private string _selected_printer;
public string selected_printer
{
get
{
return _selected_printer;
}
set
{
_selected_printer = value;
NotifyPropertyChanged(nameof(selected_printer));
}
}
My ViewModel defined:
public class PrintView: INotifyPropertyChanged
My Property Changed Stuff:
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
CodePudding user response:
You don't need to use App.xaml
to be able to create global resources. You could create your own application-wide service class and set up your view model(s) there:
public sealed class ApplicationService
{
private ApplicationService() { }
public static ApplicationService Instance { get; } = new ApplicationService();
public PrintView PrintView { get; } = new PrintView();
}
Usage:
DataContext="{Binding PrintView, Source={x:Static local:ApplicationService.Instance}}"
This is basically how a view-model locator works (assuming PrintView
is actually a view model despite its name...)