在另一个窗口文本框中加载wpf Datagrid数据

时间:2013-01-07 18:05:59

标签: c# sql-server wpf datagrid

我想在另一个窗口的文本框中重复datagrid数据。数据已保存在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>

2 个答案:

答案 0 :(得分:1)

由于您已经在使用数据绑定来填充DataGrid控件中的单元格,通过对UI代码绑定到的数据结构(您的DataContext绑定的对象)进行混洗,您应该能够实现你想要的是什么。

我整理了一个快速简化的例子。我创建了MyViewModel类作为“绑定目标”,并创建了MyView类来表示您的view / 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的setter时,不仅要更新它并引发PropertyChanged事件。我还构造了一个新的ExtraInformation对象并将其分配给ExtrStuff。回顾一下MyView.xaml,您会看到底部的两个文本框的TextProperty绑定到此对象的整数和双字段。每次用户选择这些项目之一时,都会显示一组新的随机数。

虽然这并不会让您一直从数据库中查找有关所选项目的信息,但希望它能指出您如何使用WPF数据绑定干净利落地完成此任务。文本字段所在的窗口无关紧要 - 在大多数情况下,您应该能够将两个窗口的DataContext连接到相同的底层MyViewModel。这是关于这种方法的很酷的部分。 MyViewModel类封装了如何查找存储在数据库中的有关所选项的信息。 MyView只看到它绑定的一些数据被更新,并让MyViewModel知道用户何时点击了DataGrid中的另一个项目。实际上,您可以在绑定目标中以逻辑方式构建数据。然后你只需告诉视图部分如何“绑定”绑定。这也意味着不同的视图可以以不同的方式“锁定”。也许Window1有一个绑定到Items的DataGrid,Window2有一些文本字段绑定到SelectedItem和ExtraStuff上的两个信息,也许Window3有一个显示的图像与SelectedItem相关联。每个Window / View只是绑定目标(此处为MyViewModel实例)中数据的不同可视化表示。

这是一个简单的图表,展示了这个想法:

quick Paint diagram of data binding from two views to one viewmodel, on different windows

答案 1 :(得分: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();

            }
        }

当点击Button时,数据也显示在textBoxes上,但是当我以这种方式添加Picture时,无法正常工作!