Not familiar with Stylet or Caliburn, once wanted to look at Prism BUT some articles popped up, while searching about that, in my browser and read that I don't need anything else, for MVVM, other than INotifyPropertyChanged in WPF which actually is true. At some point, to make life easier, you've to get into code behind otherwise it gets too complicated to handle simple matters.
If you want to populate a second window with various properties of the SelectedItem of your DataGrid of first window, you've to set the SelectedItem as the DataContext of your second window. Here's a small example, in the MainWindow.xaml I've these:
<Grid Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<DataGrid ItemsSource="{Binding Entries}"
SelectedItem="{Binding Selected}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Dr Head" Binding="{Binding DrHead}"/>
<DataGridTextColumn Header="Cr Head" Binding="{Binding CrHead}"/>
<DataGridTextColumn Header="Dr Amount" Binding="{Binding DrAmount}"/>
<DataGridTextColumn Header="Cr Amount" Binding="{Binding CrAmount}"/>
</DataGrid.Columns>
</DataGrid>
<Button Grid.Column="1" Content="Test" Click="Button_Click"/>
</Grid>
and in MainWindow.xaml.cs, which you could move to a separate viewmodel if you wish, these:
public partial class MainWindow : Window
{
public Entry Selected { get; set; }
public ObservableCollection<Entry> Entries { get; set; }
public MainWindow() {
InitializeComponent();
Entries = new ObservableCollection<Entry>();
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e) {
var win = new SecondWindow() { DataContext = Selected };
win.Show();
}
}
public class Entry
{
public string DrHead { get; set; }
public string CrHead { get; set; }
public int? DrAmount { get; set; }
public int? CrAmount { get; set; }
}
you also could convert that click event into an ICommand/Action if you want. See in the event handler I've set the Selected property, which is bound to the SelectedItem of DataGrid, of the MainWindow/ViewModel as the DataContextofSecondWindow. In the SecondWindow.xaml` I've these:
<StackPanel>
<TextBox Text="{Binding DrHead}"/>
<TextBox Text="{Binding CrHead}"/>
<TextBox Text="{Binding DrAmount}"/>
<TextBox Text="{Binding CrAmount}"/>
</StackPanel>
When I run the App, this is what happens on button click:
EDIT
----
You can have a static Selected property in your viewModel. I've moved the code into a separate viewModel, MainVM, like this:
class MainVM
{
public static Entry Selected { get; set; }
public ObservableCollection<Entry> Entries { get; set; }
public Command ACommand { get; set; }
public MainVM() {
Entries = new ObservableCollection<Entry>();
ACommand = new Command(show, (o) => true);
}
void show(object o) {
var window = new SecondWindow();
window.Show();
}
}
and also moved the Entry model in a separate Entry.cs file. You can bind the static Selected property in MainWindow like this:
<Window x:Class="WPFTest.MainWindow"
...
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainVM />
</Window.DataContext>
<Grid Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<DataGrid ItemsSource="{Binding Entries}"
SelectedItem="{Binding Selected}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Dr Head" Binding="{Binding DrHead}"/>
<DataGridTextColumn Header="Cr Head" Binding="{Binding CrHead}"/>
<DataGridTextColumn Header="Dr Amount" Binding="{Binding DrAmount}"/>
<DataGridTextColumn Header="Cr Amount" Binding="{Binding CrAmount}"/>
</DataGrid.Columns>
</DataGrid>
<Button Grid.Column="1" Content="Test" Command="{Binding ACommand}"/>
</Grid>
</Window>
and in SecondWindow like this:
<Window x:Class="WPFTest.SecondWindow"
...
Title="SecondWindow" Height="450" Width="800">
<StackPanel DataContext="{Binding Path=(local:MainVM.Selected)}">
<TextBox Text="{Binding DrHead}"/>
<TextBox Text="{Binding CrHead}"/>
<TextBox Text="{Binding DrAmount}"/>
<TextBox Text="{Binding CrAmount}"/>
</StackPanel>
</Window>
this also will work.