1

我想在另一个窗口的文本框中重复数据网格数据。数据已保存在 sql 数据库中,并希望通过单击一个数据网格行在新窗口中检索它们。可以做?

<DataGrid Margin="0,23,0,0" AutoGenerateColumns="False" EnableRowVirtualization="True" 
                  ItemsSource="{Binding}" Name="grdPeople" VerticalContentAlignment="Center" 
                  IsReadOnly="True" DataContext="{Binding}">

            <DataGrid.Columns>                
                <DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" Width="Auto" ></DataGridTextColumn>
                <DataGridTextColumn Binding="{Binding Path=Job}" Header="Job" Width="Auto"></DataGridTextColumn>
                <DataGridTemplateColumn Header="Picture" Width="45" >
                    <DataGridTemplateColumn.CellTemplate >
                        <DataTemplate >
                            <Image Source="{Binding Path=Picture}" Width="30" Height="30" Stretch="Uniform">                                
                            </Image>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
4

2 回答 2

1

由于您已经在使用数据绑定来填充 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 实例)中数据的不同视觉表示。

这是一个演示这个想法的简单图表:

在不同窗口上从两个视图到一个视图模型的数据绑定的快速绘制图

于 2013-01-07T18:54:28.143 回答
0

我使用了这个方法,制作了一个 ChildWindow 并使用了 LINQ to SQL 类

<TextBox Width="100" Height="40" Name="txtName" Text="{Binding Name, UpdateSourceTrigger=Explicit}" 
                 Margin="371,192,84,29"></TextBox>
        <TextBox Width="100" Height="40" Name="txtFamily" Text="{Binding Family, UpdateSourceTrigger=Explicit}" 
                 Margin="228,192,226,29"></TextBox>

和一个包含 DataGrid 的主页按钮:

private void btnNewWin_Click(object sender, RoutedEventArgs e)
        {
            if (this.dataGrid1.SelectedItems.Count == 1)
            {
                ChildWindow chWin = new ChildWindow { Owner = this, DataContext = this.dataGrid1.SelectedItem };
                chWin.ShowDialog();

            }
        }

单击按钮时,文本框上也会显示数据,但是当我以这种方式添加图片时,不起作用!

于 2013-01-08T17:01:36.013 回答