如何在WPF中使用DataGridView执行绑定?

时间:2012-12-04 01:01:05

标签: c# xaml binding

我想在与主WPF表单对接的用户控件中绑定数据网格视图。但是,每当我尝试绑定数据时,它必须预先存在且不会更新。有没有办法在XAML中直接执行此操作以了解何时触发事件来更新datagridview而不是在后面的代码中执行此操作?

XAML的部分代码:

xmlns:c="clr-namespace:TestWPFMain"

<UserControl.Resources>
    <c:GridData x:Key="dataforGrid"/>
</UserControl.Resources>
<Grid>
    <DataGrid Grid.Row="2" x:Name="datagridMain" ItemsSource="{Binding Source={StaticResource dataforGrid}, Path=Results, Mode=TwoWay}" />
</Grid>

上面的UserControl代码背后:

public GridControl()
    {
        InitializeComponent();

        GridData gd = new GridData();
        gd.UpdateResults();

        //datagridMain.ItemsSource = gd.Results;  
        -- This code above will work if I uncomment but I want it to be bound 
           directly and was curious as I thought the mode of 'two way' would 
           do this.  I am not certain and most examples assume property is already
           set up and not being created and updated.
    }

GridData的代码类:

class PersonName
{
    public string Name { get; set; }
}

class GridData
{
    public ObservableCollection<PersonName> Results { get; set; }

    public void UpdateResults()
    {
        using (EntityDataModel be = new EntityDataModel())
        {
            var list = be.tePersons.Select(x => new PersonName { Name = x.FirstName });

            Results = new ObservableCollection<PersonName>(list);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

要使用这样的绑定,您需要:

  1. DataContext(或其父级之一)上正确设置DataGrid
  2. 在您的模型类上实施INotifyPropertyChanged,并在属性设置器中引发PropertyChanged
  3. 1)

    将窗口的DataContext设置为GridData对象:

    public GridControl()
    {
        InitializeComponent();
    
        GridData gd = new GridData();
        gd.UpdateResults();
        this.DataContext = gd;
    }
    

    2)

    实施INotifyPropertyChanged。这可确保在Results属性更新时通知您的视图:

    public class GridData : INotifyPropertyChanged
    {
        private ObservableCollection<PersonName> _results;
        public ObservableCollection<PersonName> Results 
        {  
            get { return _results; }
            set
            {
                _results = value;
                RaisePropertyChanged("GridData");
            }
        }
    
        // ...
    
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string prop)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
            }
        }
        #endregion
    }
    

    然后您可以简单地绑定到相对于数据上下文的路径。

    <DataGrid ItemsSource="{Binding Results}" />
    

    请注意,在这种情况下,您不需要双向绑定 - 用于将视图中的更改传播回模型(即,对于像文本框或复选框这样的UI控件时最有用)。 / p>

答案 1 :(得分:1)

这是一个例子(我使用了Window,但它对UserControl的作用相同)

的Xaml:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Name="UI">
    <Grid>
        <DataGrid Grid.Row="2" x:Name="datagridMain" ItemsSource="{Binding ElementName=UI, Path=GridData.Results, Mode=TwoWay}" />
    </Grid>
</Window>

或id你想要整个DataContext:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Name="UI">
    <Grid>
        <DataGrid Grid.Row="2" x:Name="datagridMain" DataContext="{Binding ElementName=UI, Path=GridData}" ItemsSource="{Binding Results}" />
    </Grid>
</Window>

代码:

您必须实现INotifyPropertyChanged,以便xaml知道GridData已更改 GridData内部的ObservableCollection作为此函数内置,因此无论何时添加删除项都会更新DataGrid控件

public partial class MainWindow : Window , INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        GridData = new GridData { Results = new ObservableCollection<PersonName>() };
        GridData.Results.Add(new PersonName { Name = "Test1" });
        GridData.Results.Add(new PersonName { Name = "Test2" });
    }

    private GridData _gridData;
    public GridData GridData
    {
        get { return _gridData; }
        set { _gridData = value; NotifyPropertyChanged("GridData"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    /// <summary>
    /// Notifies the property changed.
    /// </summary>
    /// <param name="info">The info.</param>
    public void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

类: 我对update方法进行了一些小改动,所以它只是清除并更新了现有的ObservableCollection,否则如果你指定一个新的ObservableCollection,你必须实现INotifypropertyChanged到这个类。

public class PersonName
{
    public string Name { get; set; }
}

public class GridData
{
    public GridData()
    {
       Results = new ObservableCollection<PersonName>()
    }

    public ObservableCollection<PersonName> Results { get; set; }

    public void UpdateResults()
    {
        using (EntityDataModel be = new EntityDataModel())
        {
            // Just update existing list, instead of creating a new one.
           Results.Clear();
           be.tePersons.Select(x => new PersonName { Name = x.FirstName }).ToList().ForEach(item => Results.Add(item);
        }
    }
}