C# 如何在WPF中执行与DataGridView的绑定?

C# 如何在WPF中执行与DataGridView的绑定?,c#,xaml,binding,C#,Xaml,Binding,我想在一个用户控件中绑定一个datagrid视图,该控件停靠在一个主WPF表单上。但是,每次我尝试绑定数据时,它必须预先存在,并且不会更新。有没有一种方法可以在XAML中直接执行此操作,以了解何时触发事件来更新datagridview,而不是在代码隐藏中执行此操作 XAML的部分代码: xmlns:c="clr-namespace:TestWPFMain" <UserControl.Resources> <c:GridData x:Key="dataforGrid"/

我想在一个用户控件中绑定一个datagrid视图,该控件停靠在一个主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>
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);
        }
    }
}

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

在DataGrid或其父级上正确设置DataContext 在模型类上实现INotifyPropertyChanged,并在属性设置器中引发PropertyChanged。 1. 将窗口的DataContext设置为GridData对象:

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}" />

请注意,在这种情况下,您不需要双向绑定-这是为了将更改从视图传播回您的模型ie,对于有文本框或复选框之类的UI控件的情况最为有用。

这里是我使用的窗口示例,但对UserControl也同样适用

Xaml:

或您想要整个DataContext的id:

<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内部的ObservaleCollection内置了此函数,因此无论何时添加或删除项,它们都会更新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);
        }
    }
}

感谢dbaseman,我觉得添加一个连接到接口的事件可能会起到作用,但我不知道该使用什么。正是我想要的。
<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>
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));
        }
    }
}
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);
        }
    }
}