【问题标题】:Load wpf Datagrid data in another window text boxes在另一个窗口文本框中加载 wpf Datagrid 数据
【发布时间】:2013-01-07 18:05:59
【问题描述】:

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

【问题讨论】:

    标签: c# sql-server wpf datagrid


    【解决方案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 实例)中数据的不同视觉表示。

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

    【讨论】:

    【解决方案2】:

    我使用了这个方法,制作了一个 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();
    
                }
            }
    

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

    【讨论】:

      猜你喜欢
      • 2012-12-21
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多