Hallo
Ich bin Anfänger und beschäftige mich gerade mit Binding bei WPF
Ich habe mir eine Klasse erstelle wo die Variablen drin sind.
Meine Klasse
namespace WPF_C_DB_Lernen
{
class Binding_Klasse
{
public string ButtonName { get; set; }
public void ButtonNameTest()
{
ButtonName = "Hallo";
}
}
}
mein MainWindow
namespace WPF_C_DB_Lernen
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Binding_Klasse BindingKlasse = new Binding_Klasse();
BindingKlasse.ButtonNameTest();
// Button1.Content = BindingKlasse.ButtonName;
}
}
}
Mein WPF
<Window x:Class="WPF_C_DB_Lernen.MainWindow"
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:WPF_C_DB_Lernen"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button x:Name="Button1" Content="{Binding Path=ButtonName}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="121" Height="67"/>
</Grid>
</Window>
Wenn ich mein Button ein x:Name gebe und per Code mit .Content = BindingKlasse.ButtonName reinschreibe dann funktioniert das. aber es sollte ja auch ohne gehen.
Was habe ich da falsch gemacht?
Gruß
Mattes
Dein ViewModel muß das INotifyPropertyChanged-Interface implementieren. Hier gibt es eine ausführlichere Erklärung dazu: [Artikel] MVVM und DataBinding
Weeks of programming can save you hours of planning
Hallo Danke für deine Antwort.
Mein Code sieht nun so aus.
Meine Klasse:
namespace WPF_C_DB_Lernen
{
class Binding_Klasse : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string _ButtonName;
public string ButtonName
{
get { return _ButtonName; }
set
{
if (value != _ButtonName)
{
_ButtonName = value;
OnPropertyChanged("ButtonName");
}
}
}
public void ButtonNameTest()
{
ButtonName = "Hallo";
}
}
}
mein MainWindow:
namespace WPF_C_DB_Lernen
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Binding_Klasse BindingKlasse = new Binding_Klasse();
this.DataContext = BindingKlasse;
BindingKlasse.ButtonNameTest();
}
}
}
Mein WPF:
<Window x:Class="WPF_C_DB_Lernen.MainWindow"
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:WPF_C_DB_Lernen"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:Binding_Klasse />
</Window.DataContext>
<Grid>
<Button x:Name="Button1" Content="{Binding ButtonName}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="121" Height="67"/>
</Grid>
</Window>
Nun noch eine Frage, kann man auch mehrere Klassen mit DataContext machen oder nur mit 1er Klasse?
Wenn es mit mehrere geht, wie funktioniert das dann?
Gruß
Mattes
Servus,
warum definierst Du den DataContext im XAML und im Code behind?
Hallo
So habe ich es in dem Tutorial rausgelesen.
Ich bin für jede Verbesserung dankbar will es ja auch richtig Lernen
Gruß
Mattes
Da steht aber: "Oder alternativ mit Hilfe von XAML".
Alternativ 😃
kann man auch mehrere Klassen mit DataContext machen oder nur mit 1er Klasse?
DataContext kann nur ein Objekt zugewiesen werden. Normalerweise hat das Fenster ein MainViewModel, und die einzelnen Unterbereiche im Fenster dann spezielle Unter-ViewModels, welche als Eigenschaften im MainViewModel liegen. Das kann beliebig verschachtelt werden.
Ansonsten würde ich empfehlen, statt OnPropertyChanged("ButtonName")
besser OnPropertyChanged(nameOf(ButtonName))
zu schreiben, weil dann die Bindung nicht verloren geht, wenn du die Eigenschaft mal umbenennst.
Und deine Binding_Klasse
würde ich lieber MainViewModel
oder ButtonViewModel
nennen, dann ist klar, welche Aufgabe die Klasse hat.
Weeks of programming can save you hours of planning
Danke für deine Antwort
Was wäre besser in XAML oder in Code Behind?
Also ist nur 1 ViewModel möglich wenn ich es Richtig verstanden habe.
Ich hätte gerne verschiedene für
ButtonViewModel
LabelViewModel
TextboxViewModel
Dazu würde noch eine Extra Klasse kommen für SQLite Abfragen.
In der Regel wird alles im XAML definiert. Im MVVM Pattern wird normalerweise nichts, aber auch gar nichts im Code behind programmiert.
Und ich fürchte, du hast ein Verständnisproblem mit den View Models. Willst Du für jedes Steuerelement ein eigenes ViewModel machen? Also auch ein CheckBoxViewModel, RadioButtonViewModel, TextBlockViewModel, DataGridViewModel, ...?
Was müssen Deine ViewModels außergewöhnliches können - außer Text anzeigen - dass man dies so wie von Dir gewünscht, definieren müßte?
Ändert sich die Ansicht?
Hallo
mein Beispiel war ein schlechtes Beispiel. Es geht nicht um die einzelne Steuerelemente.
Ich möchte eine Trennung Zwischen Sprachanzeigen, Datenbankanzeigen und Funktionsanzeigen.
z.b.
Die ein WPF-Fenster würde ich gern ein SprachViewModel, DatenbankViewModel, und ein FunktionViewModen und sogar ein FunktionKlasse.
Damit will ich mit selber einen Besseren Überlick beschaffen und nicht alles in einer ViewModel reinpacken.
Vielleicht denke ich ein bissen zu Kompliziert.
Ich sag ja immer warum einfach wenn es ja auch Kompliziert geht 😃
Gruß
Mattes
Hallo Mattes80,
DataContext kann nur ein Objekt zugewiesen werden. Normalerweise hat das Fenster ein MainViewModel, und die einzelnen Unterbereiche im Fenster dann spezielle Unter-ViewModels, welche als Eigenschaften im MainViewModel liegen. Das kann beliebig verschachtelt werden.
Nach dem Schema würde ich auch vorgehen und du könntest es dann zB so schachteln:
MainViewModel
-> SprachViewModel
-> DatenbankViewModel
-> FunktionsViewModel
Die Struktur kannst du auch in Form von verschachtelten Views wiederspiegeln und zB eine ähnliche Struktur in den Views anlegen:
MainView
-> SprachView
-> DatenbankView
-> FunktionsView
Das Hauptfenster bekommt als DataContext dann das MainViewModel und alles weitere ergibt sich rein aus den Bindings:
<Window x:Class="WpfApp1.MainWindow"
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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainViewModel></local:MainViewModel>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<local:SprachView Grid.Column="0" DataContext="{Binding Path=SprachViewModel}"></local:SprachView>
<local:DatenbankView Grid.Column="1" DataContext="{Binding Path=DatenbankViewModel}"></local:DatenbankView>
<local:FunktionsView Grid.Column="2" DataContext="{Binding Path=FunktionsViewModel}"></local:FunktionsView>
</Grid>
</Window>
<UserControl x:Class="WpfApp1.SprachView"
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:wpfApp1="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance wpfApp1:SprachViewModel}">
<Grid>
<ListView ItemsSource="{Binding Sprachen}" />
</Grid>
</UserControl>
und die entsprechenden ViewModels stark vereinfacht:
public class MainViewModel
{
public SprachViewModel SprachViewModel { get; set; } = new SprachViewModel();
public DatenbankViewModel DatenbankViewModel { get; set; } = new DatenbankViewModel();
public FunktionsViewModel FunktionsViewModel { get; set; } = new FunktionsViewModel();
}
public class SprachViewModel
{
public List<string> Sprachen { get; set; } = new List<string> {"Deutsch", "Englisch"};
}
public class DatenbankViewModel
{
public List<string> Datenbanken { get; set; } = new List<string> {"DbA", "DbB"};
}
public class FunktionsViewModel
{
public List<string> Funktionen { get; set; } = new List<string> {"DoSomething", "DoSomethingElse"};
}
Lg, XXX
Hallo danke für deine Antwort
Das sieht ja schon mal sehr interessant aus. Das werde ich gleich mal heute Abend Testen.
Gruß
Mattes