I have written a WPF application. It has the following views:
- AddStockView.cs (It is used to add stocks)
- StockBox.cs (Represents a combo box that displays all the stocks).
- View.cs (for MainWindow.xaml)
Of course, each view has an xaml file. Both views should be linked to the ViewModel class. To make sure that the DataContext of both views points to the same ViewModel object, I passed it as a constructor parameter. I am compiling the application in Visual Studio code. The compile seems to work however no window start. Probably my approach is wrong. I wanted to ask you what I need to change to make the application behave correctly. App.xaml.cs
namespace analyser
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
// Statische SQLiteConnection-Instanz für die gesamte Anwendung
public static StockDBContext stockDBContext = new StockDBContext();
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ViewModel viewModel = new ViewModel();
StockBoxView stockboxview = new StockBoxView(viewModel);
AddStockView addstockview = new AddStockView(viewModel);
// Methode zum Hinzufügen von Stock-Objekten in die Datenbank
stockDBContext.Stocks.Add(new Stock { Wkn = "123456", Titel = "Porsche Automobil Holding" });
stockDBContext.Stocks.Add(new Stock { Wkn = "654321", Titel = "PayPal" });
stockDBContext.SaveChanges();
}
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
}
}
}
View 1 AddStockView.cs
namespace analyser
{
public partial class AddStockView : UserControl
{
public AddStockView(ViewModel vm)
{
InitializeComponent();
this.DataContext = vm;
}
}
}
<UserControl x:Class="analyser.AddStockView"
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"
xmlns:local="clr-namespace:analyser">
<Grid>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10">
<!-- Überschrift "Add new Stocks" -->
<TextBlock Text="Add new Stocks" FontSize="20" FontWeight="Bold" Margin="0,0,0,20" />
<!-- TextBox für den Namen des Wertpapiers -->
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Label Content="Name des Wertpapiers:" FontSize="16" Width="200" />
<TextBox x:Name="TitelTextBox" Width="200" Margin="10,0" FontSize="16" Text="{Binding Titel, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
<!-- TextBox für die WKN des Wertpapiers -->
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Label Content="WKN des Wertpapiers:" FontSize="16" Width="200" />
<TextBox x:Name="WknTextBox" Width="200" Margin="10,0" FontSize="16" Text="{Binding Wkn, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<!-- Absendebutton (linksbündig) -->
<Button Width="150" Content="Absenden" HorizontalAlignment="Left" Command="{Binding SaveCommand}" />
</StackPanel>
</Grid>
</UserControl>
View 2 StockBox
namespace analyser
{
public partial class StockBoxView : UserControl
{
public StockBoxView(ViewModel vm)
{
InitializeComponent();
this.DataContext = vm;
}
}
}
<UserControl
x:Class="analyser.StockBoxView"
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"
xmlns:local="clr-namespace:analyser">
<Grid>
<StackPanel>
<!-- Verwenden Sie das Binding auf die ObservableCollection<Stock> ObservableStockList -->
<ComboBox x:Name="StockComboBox" Width="150" SelectedIndex="0"
ItemsSource="{Binding ObservableStockList}"
DisplayMemberPath="Titel" />
</StackPanel>
</Grid>
</UserControl>
ViewModel.cs
namespace analyser
{
public class ViewModel : INotifyPropertyChanged
{
private Stock stock = new Stock();
public ObservableCollection<Stock> ObservableStockList = new ObservableCollection<Stock>();
private ListCollectionView ComboBoxItems;
public ViewModel()
{
// Initialisierung der ObservableStockList und ComboBoxItems
Init();
}
// Property für den Namen des Wertpapiers
private string _titel;
public string Titel
{
get => _titel;
set
{
_titel = value;
OnPropertyChanged(nameof(Titel));
}
}
// Property für die WKN des Wertpapiers
private string _wkn;
public string Wkn
{
get => _wkn;
set
{
_wkn = value;
OnPropertyChanged(nameof(Wkn));
}
}
private ICommand _saveCommand;
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
_saveCommand = new RelayCommand(Save);
return _saveCommand;
}
}
public void Init(){
foreach (var stock in App.stockDBContext.Stocks)
{
ObservableStockList.Add(stock);
}
// Erstellen und Konfigurieren Sie den ListCollectionView
ComboBoxItems = new ListCollectionView(ObservableStockList);
ComboBoxItems.SortDescriptions.Add(new SortDescription("Titel", ListSortDirection.Ascending));
ComboBoxItems.IsLiveSorting = true;
}
public void Save()
{
// Speichern Sie die Werte der Textboxen in das Stock-Objekt
stock.Titel = Titel;
stock.Wkn = Wkn;
Console.WriteLine($"Generate new Stock with Titel {stock.Titel} and WKN {stock.Wkn}");
App.stockDBContext.Stocks.Add(stock);
// Hier können Sie die Logik zum Speichern des Stock-Objekts in die Datenbank oder an einen anderen Speicherort einfügen.
}
// ... (weiterer Code wie die Implementierung von INotifyPropertyChanged)
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
MainWindow.xaml
<Window x:Class="analyser.View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:analyser"
xmlns:uc="clr-namespace:analyser"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<!-- Define a style for TabItem -->
<Style TargetType="TabItem">
<Setter Property="FontSize" Value="16" /> <!-- Set the desired font size (e.g., 16) -->
</Style>
</Window.Resources>
<Grid>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="_New"/>
<MenuItem Header="_Open"/>
<Separator />
<MenuItem Header="_Exit" />
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_About"/>
</MenuItem>
</Menu>
<TabControl>
<TabItem Header="add Stock">
<!-- Content for Tab 1 -->
<uc:AddStockView/>
</TabItem>
<TabItem Header="auswählen">
<!-- Content for Tab 1 -->
<uc:StockBoxView/>
</TabItem>
<TabItem Header="Tab 2">
<!-- Content for Tab 2 -->
</TabItem>
<TabItem Header="Tab 3">
<!-- Content for Tab 3 -->
<TextBlock Text="This is Tab 3 content."/>
</TabItem>
</TabControl>
</DockPanel>
</Grid>
</Window>
View.cs
namespace analyser
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class View : Window
{
public View()
{
InitializeBindings();
}
private void InitializeBindings() {
DataContext = this;
}
}
}
Edit
MyProjekt
|___Views
| |___AddStock
| | |___AddStock.xaml (UserControl)
| | |___AddStock.xaml.cs
| |___StockBox
| |___StockBox.xaml (UserControl)
| |___StockBox.xaml.cs
|
|___ViewModels
| |___ViewModel.cs
|
|___Models
| |___Stock.cs
| |___StockBoxDBContext
|
|___App.xaml
|___App.xaml.cs
|___MainWindow.xaml
|___MainWindow.xaml.cs
You must not explicitly assign the
DataContextof a control. You should strive to enable the XAML parser to create the instances for you so that you can use markup language to design the layout conveniently.Unless you explicitly assign a
DataContextto an element theDataContextof the root element will be inherited to all children within the visual tree. This means you usually only assign theDataContextof the XAML root element.You can use composition to design your view model classes to introduce a context specific
DataContextto your layout (see example below).The following example shows how to run the main window manually to allow to pass a view model to the constructor. It also shows how to use composition to introduce context related view model classes.
App.xaml
App.xaml.cs
MainWindow.xaml
MainWindow.xaml.cs
MyUserControl.xaml.cs
MyUserControl.xaml.cs
MainViewModel.cs
SomeViewModel.cs