問題描述
WPF MVVM 鏈接視圖 (WPF MVVM Linked Views)
I need some help regarding my first MVVM WPF application. I want to link two views on my main window. Here's the situation:
I have for instance these two viewmodels:
‑ PersonDetailViewModel
‑ PersonListViewModel
PersonListViewModel contains : ‑ an ObservableCollection
of PersonDetailViewModels
called People ‑ one PersonDetailViewMode
l which is accessible through a public property called "SelectedPerson"
I also have created two views: PersonListView
, which lists all persons in a datagrid. PersonDetailView
, which is simply a bunch of labels and textboxes bound to the viewmodel
PersonDetailViewModel
.
I want to use these two together on my MainWindow. But I have no idea how the make this work! Here's what I have so far:
PersonListView.xaml
<UserControl x:Class="DSS.View.PersonListView"
...
xmlns:myViewModels="clr‑namespace:DSS.ViewModel">
<UserControl.DataContext>
<myViewModels:PersonListViewModel/>
</UserControl.DataContext>
<Grid>
<DataGrid x:Name="dgPeople" ItemsSource="{Binding People}" AutoGenerateColumns="False" IsReadOnly="True" ColumnWidth="*"
SelectedItem="{Binding SelectedPerson}">
<DataGrid.Columns>
<DataGridTextColumn Header="PersonId" Binding="{Binding PersonId}" Visibility="Hidden"/>
<DataGridTextColumn Header="Firstname" Binding="{Binding Firstname}"/>
<DataGridTextColumn Header="Lastname" Binding="{Binding Lastname}"/>
...
</DataGrid.Columns>
</DataGrid>
</Grid>
PersonDetailView.xaml:
<UserControl x:Class="DSS_CV.View.PersonDetailView"
...
xmlns:myViewModels="clr‑namespace:DSS.ViewModel">
<UserControl.DataContext>
<myViewModels:PersonDetailViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.ColumnDefinitions>... </Grid.ColumnDefinitions>
<Grid.RowDefinitions>...</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0">Firstname:</Label>
<TextBox Grid.Row="0" Grid.Column="1" x:Name="txtFirstName" Text="{Binding Path=Firstname}"></TextBox>
<Label Grid.Row="1" Grid.Column="0">Lastname:</Label>
<TextBox Grid.Row="1" Grid.Column="1" x:Name="txtLastName" Text="{Binding Path=Lastname}"></TextBox>
<Label Grid.Row="2" Grid.Column="0">Birthdate:</Label>
<TextBox Grid.Row="2" Grid.Column="1" x:Name="txtBirtDate" Text="{Binding Path=DateOfBirth}"></TextBox>
...
<WrapPanel Grid.Row="7" Grid.ColumnSpan="5">
<Button>Update</Button>
<Button>Insert As New</Button>
</WrapPanel>
</Grid>
Now, I would like to combine/link these usercontrols in one window so they work together in a way that selecting a row from the datagrid allows to edit the details in the other usercontrol.
MainWindow.xaml:
<Window x:Class="DSS_CV.MainWindow"
...
xmlns:myViews="clr‑namespace:DSS_CV.View">
<Grid>
<myViews:PersonListView x:Name="dgPersons" Grid.Row="0" Grid.Column="0"/>
<myViews:PersonDetailView Grid.Row="1" Grid.Column="0" DataContext="{Binding dgPersons.SelectedPerson, Mode=TwoWay}"/>
</Grid>
</Window>
INotifyPropertyChanged
is implemented everywhere in my classes and the selecting a different row in PersonListView
updates its property SelectedPerson
correctly. Now I do not see how I can bind the datacontext of PersonDetailView
to that SelectedPerson
. If anyone could help me.
參考解法
方法 1:
Change
<myViews:PersonDetailView Grid.Row="1" Grid.Column="0" DataContext="{Binding dgPersons.SelectedPerson, Mode=TwoWay}"/>
To
<myViews:PersonDetailView Grid.Row="1" Grid.Column="0" DataContext="{Binding Path=DataContext.SelectedPerson ElementName=dgPersons, Mode=TwoWay}"/>
(by user2135342、Bill Zhang)