1

我想在停靠到主 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);
        }
    }
}
4

2 回答 2

1

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

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

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 控件时最有用)。

于 2012-12-04T01:12:23.903 回答
1

这是一个示例(我使用了 Window,但它对 UserControl 也一样)

xml:

<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);
        }
    }
}
于 2012-12-04T01:18:28.223 回答