由于您已经在使用数据绑定来填充 DataGrid 控件中的单元格,因此通过改组您的 UI 代码绑定到的数据结构(您的 DataContext 绑定到的对象),您应该能够实现您的目标再去。
我整理了一个快速、简化的示例。我创建了 MyViewModel 类作为“绑定目标”,并创建了 MyView 类来表示您的视图/xaml。首先,与您上面的代码类似,MyView 有一个 DataGrid。我还在 DataGrid 下方的同一个用户控件中添加了几个文本框。两个是所选项目的名称和工作字段。另外两个应该是您要根据用户的选择填充的其他字段。例如,当用户选择一行时,它们可能是您从数据库中查找的额外数据。这是 MyView.xaml:
<UserControl x:Class="WpfApplication1.MyView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}"
IsReadOnly="True" SelectedItem="{Binding SelectedItem}"
SelectionMode="Single">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Job" Binding="{Binding Job}"/>
</DataGrid.Columns>
</DataGrid>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<TextBox Width="100" Text="{Binding SelectedItem.Name, Mode=OneWay}" Margin="2"/>
<TextBox Width="100" Text="{Binding SelectedItem.Job, Mode=OneWay}" Margin="2"/>
<TextBox Width="100" Text="{Binding ExtraStuff.ExtraIntegerField, Mode=OneWay}" Margin="2"/>
<TextBox Width="100" Text="{Binding ExtraStuff.ExtraDoubleField, Mode=OneWay}" Margin="2"/>
</StackPanel>
</Grid>
现在,对于 DataGrid 的绑定,我将 ItemsSource 绑定到控件的 DataContext 上的特定集合。所以在这里,DataContext 不是集合本身,而是一个包含行的项目和一些其他信息的对象。我还将 SelectedItem 绑定到一个名为 SelectedItem 的属性,该属性应具有公共 getter 和 setter。然后将 MyView 的 DataContext 设置为 MyViewModel 的一个实例。这是 MyViewModel.cs:
public sealed class MyViewModel : INotifyPropertyChanged
{
private readonly ObservableCollection<LightItem> _items = new ObservableCollection<LightItem>();
private LightItem _selectedItem;
private ExtraInformation _extraStuff;
public MyViewModel()
{
this._items.Add(new LightItem("Tim", "Dish Washer"));
this._items.Add(new LightItem("Bob", "Window Washer"));
this._items.Add(new LightItem("Jill", "Widget Washer"));
}
public event PropertyChangedEventHandler PropertyChanged;
public ExtraInformation ExtraStuff
{
get { return this._extraStuff; }
private set
{
this._extraStuff = value;
this.OnPropertyChanged("ExtraStuff");
}
}
public ReadOnlyObservableCollection<LightItem> Items { get { return new ReadOnlyObservableCollection<LightItem>(this._items); } }
public LightItem SelectedItem
{
get { return this._selectedItem; }
set
{
this._selectedItem = value;
this.OnPropertyChanged("SelectedItem");
this.ExtraStuff = new ExtraInformation(value);
}
}
private void OnPropertyChanged(string name)
{
if (null != this.PropertyChanged)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public sealed class ExtraInformation
{
private readonly double _extraDoubleField;
private readonly int _extraIntegerField;
public ExtraInformation(LightItem light)
{
// you could get more info for your record from the db
// but here we just get some random numbers
var rnd = new Random();
this._extraDoubleField = rnd.NextDouble();
this._extraIntegerField = rnd.Next();
}
public double ExtraDoubleField { get { return this._extraDoubleField; } }
public double ExtraIntegerField { get { return this._extraIntegerField; } }
}
public sealed class LightItem
{
private readonly string _job;
private readonly string _name;
public LightItem(string name, string job)
{
this._name = name;
this._job = job;
}
public string Job { get { return this._job; } }
public string Name { get { return this._name; } }
}
}
在这里,属性 SelectedItem 与我们绑定到 DataGrid 上的 SelectedItem 依赖属性的属性相同。它的类型与我的 Items 集合中的项目类型相同,该集合绑定到 DataGrid 的 ItemsSource。现在,当调用 SelectedItem 的设置器时,不仅要更新它并引发 PropertyChanged 事件。我还构造了一个新的 ExtraInformation 对象并将其分配给 ExtrStuff。回顾一下 MyView.xaml,您会看到底部的两个文本框的 TextProperty 绑定到该对象上的 integer 和 double 字段。每次用户选择其中一项时,都会显示一组新的随机数。
虽然这不会带您一路从数据库中查找有关所选项目的信息,但希望它为您指明正确的方向,即如何使用 WPF 数据绑定干净地完成此操作。文本字段位于哪个窗口无关紧要 - 在大多数情况下,您应该能够将两个窗口的 DataContext 连接到相同的底层 MyViewModel。这就是这种方法最酷的部分。MyViewModel 类封装了如何查找存储在数据库中的有关所选项目的信息。MyView 只是看到它绑定的一些数据被更新,并让 MyViewModel 知道用户何时单击了 DataGrid 中的不同项目。实际上,您在绑定目标中逻辑地构建数据的外观。然后,您只需告诉视图部分如何使用绑定“锁定”。这也意味着不同的观点可以以不同的方式“锁定”。也许 Window1 有一个绑定到 Items 的 DataGrid,Window2 有一些文本字段绑定到 SelectedItem 和 ExtraStuff 的信息,也许 Window3 显示了一个与 SelectedItem 相关联的图像。每个窗口/视图只是绑定目标(此处为 MyViewModel 实例)中数据的不同视觉表示。
这是一个演示这个想法的简单图表: