如何使用XAML将DataGrid绑定到CollectionViewSource

6
我有一个数据网格,它绑定到一个CollectionViewSource,该CollectionViewSource绑定到一个ObservableCollection。按照指南的步骤设置如下:
我的Persons类:
public class Persons : ObservableCollection<Person>
{
    //...
}

XAML 数据绑定:

<Window.Resources>
    <local:Persons x:Key="_Persons"/>
    <CollectionViewSource x:Key="cvsPersons" Source="{StaticResource _Persons}" />                       
</Window.Resources>

数据网格绑定:
 <DataGrid x:Name="myDataGrid" ItemsSource="{Binding Source={StaticResource cvsPersons}}"/>

代码背后:

_Persons = (Persons)this.Resources["_Persons"];
_persons = //some method to fill perons;
cvsPersons = (CollectionViewSource)this.Resources["cvsPersons"];             
cvsPersons.Source = _Persons;

上述工作正常。我的问题是,为什么我需要在代码后台中设置collectionviewsource.source,使用cvsPersons.Source = _Persons;?我认为我在第一个代码片段中的xaml已经完成了这个任务:
_cvsPersons.Source = _Persons;  

如果我需要所有这些后端代码,那么 XAML 数据绑定代码似乎毫无益处,我可能只需在后台代码中完成所有操作。根据我的理解(也许只是片面的),在后台代码中只需要引用由 XAML 设置的实例即可,例如:
_Persons = (Persons)this.Resources["_Persons"];
_persons = //some method to fill perons;
cvsPersons = (CollectionViewSource)this.Resources["cvsPersons"];

如果我不写_cvsPersons.Source = _Persons;,那么我的数据表格就不会被填充。目前我的XAML不能完成这个任务。我想我的问题更多是概念上的。
1个回答

10

为了避免你的代码后端方法,你应该使用MVVM模式 MVVM模型视图视图模型。可能的解决方案是创建一个像这样的“Person”(作为模型):

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
你可以实现一个ViewModel,使用Person的ObservableCollection属性进行初始化。
public class ViewModel
{
    public ObservableCollection<Person> Persons { get; set; }

    public ViewModel()
    {
        Persons = new ObservableCollection<Person>();
    }
}

您的MainWindow.cs现在必须初始化ViewModel:

public partial class MainWindow : Window
{
    public ViewModel ViewModel;

    public MainWindow()
    {
        ViewModel = new ViewModel();

        ViewModel.Persons.Add(new Person
        {
            Age = 29,
            Name = "Mustermann"
        });

        ViewModel.Persons.Add(new Person
        {
            Age = 35,
            Name = "Meyer"
        });

        this.DataContext = ViewModel;

        InitializeComponent();
    }

将DataContext设置为ViewModel对象非常重要。我添加了一个按钮和一个用于添加人员的方法。

    private void AddPersonOnClick(object sender, RoutedEventArgs e)
    {
        ViewModel.Persons.Add(new Person
        {
            Age = 55,
            Name = "Sand"
        });
    }

现在你可以在 XAML 中实例化 CollectionViewSource,并将其绑定到 ViewModel 中 Persons ObservableCollection 属性。

<Window x:Class="DataGridStackoverflow.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">
<Window.Resources>
    <CollectionViewSource x:Key="PersonsCollectionViewSource" Source="{Binding Persons}" />
</Window.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <DataGrid Grid.Row="0" ItemsSource="{Binding Source={StaticResource PersonsCollectionViewSource}}" />
    <Button x:Name="AddPerson" Grid.Row="1" Click="AddPersonOnClick" HorizontalAlignment="Left">Add Person</Button>
</Grid>

最后,您需要将ItemsSource设置为您将其发布到CollectionViewSource中,它可以完美运行。

编辑

我尝试了您的解决方案,它也能正常工作。MainWindow.xaml:

    <Window.Resources>
    <dataGridStackoverflow:Persons x:Key="Persons" />
    <CollectionViewSource x:Key="PersonsCollectionViewSource" Source="{StaticResource Persons}" />
</Window.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <DataGrid Grid.Row="0" ItemsSource="{Binding Source={StaticResource PersonsCollectionViewSource}}" />
    <Button x:Name="AddPerson" Grid.Row="1" Click="AddPersonOnClick" HorizontalAlignment="Left">Add Person</Button>
</Grid>

InitializeComponent()之后初始化您的Persons Collection是很重要的。MainWindow.cs

        InitializeComponent();
        Persons persons = (Persons)this.FindResource("Persons");

        persons.Add(new Person
        {
            Age = 23,
            Name = "Dude"
        });

这种解决方案不需要使用代码后台结构来设置ItemsSource。


1
非常感谢。已经运行成功了。对于 MVVM 方法的建议,谢谢大家。 - AdVic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接