c# - 有没有一种方法可以使用ObservableCollection和MVVM刷新WPF DataGrid,而无需通知ItemsSource集合?

标签 c# wpf mvvm datagrid observablecollection

这是我的第一个问题,所以我会努力的。

我正在尝试使用ObservableCollection和MVVM“刷新”一个简单的WPF DataGrid控件,正如网络上的许多教程所述。

在上下文中,这些是我的模型分类:

(PersonViewModel.cs)

public class PersonViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private int _id;
    private int _idAddress;
    private string _name;
    private int _age;
    private string _address;

    public int Id
    {
        get { return this._id; }
        set
        {
            if (value != this._id)
            {
                this._id = value;
                OnPropertyChanged();
            }
        }
    }
    public int IdAddress
    {
        get { return this._idAddress; }
        set
        {
            if (value != this._idAddress)
            {
                this._idAddress = value;
                OnPropertyChanged();
            }
        }
    }
    public string Name
    {
        get { return this._name; }
        set
        {
            if (value != this._name)
            {
                this._name = value;
                OnPropertyChanged();
            }
        }
    }
    public int Age
    {
        get { return this._age; }
        set
        {
            if (value != this._age)
            {
                this._age = value;
                OnPropertyChanged();
            }
        }
    }
    public string Address
    {
        get { return this._address; }
        set
        {
            if (value != this._address)
            {
                this._address = value;
                OnPropertyChanged();
            }
        }
    }

    private void OnPropertyChanged([CallerMemberName]String caller = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(caller));
        }
    }
}

(AddressViewModel.cs)
public class AddressViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private int _id;
    private string _street;
    private int _number;

    public int Id
    {
        get { return this._id; }
        set
        {
            if (value != this._id)
            {
                this._id = value;
                OnPropertyChanged();
            }
        }
    }
    public string Street
    {
        get { return this._street; }
        set
        {
            if (value != this._street)
            {
                this._street = value;
                OnPropertyChanged();
            }
        }
    }
    public int Number
    {
        get { return this._number; }
        set
        {
            if (value != this._number)
            {
                this._number = value;
                OnPropertyChanged();
            }
        }
    }

    private void OnPropertyChanged([CallerMemberName]String caller = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(caller));
        }
    }
}

这是数据库模型的表示形式(无法上传图片<10个帖子)

地址

ID
街道
数字



ID
ID地址
姓名
年龄
地址--->此属性连接“街道”和“地址数”实体。

因此,如您所见,这是一个非常简单的示例。只是概念证明。问题是,每当我尝试通过Entity Framework 6和LINQ向数据库中添加新实体时,都不可避免地必须将该ViewModel实体添加到DataGrid的数据上下文中。

这是直到今天的代码:
public static Person CreatePerson(PersonViewModel personVM)
{
    var person = new Person
    {
        IdAddress = personVM.IdAddress,
        Name = personVM.Name,
        Age = personVM.Age
    };

    try
    {
        using (var context = new OCDemoContext())
        {
            context.Database.Connection.Open();
            context.Person.Add(person);
            context.SaveChanges();
            context.Database.Connection.Close();
        }
    }
    catch
    {
        throw;
    }

    return person;
}

如您所见,这里需要在DataGrid中显示一列,该列连接Address数据库实体的两个属性:Street和Number,并将该值提供给PersonViewModel类的Address属性以在DataGrid中显示为一列。

将实体插入数据库后,将实体添加到DataGrid itemssource集合的代码:
        // Add to the database
        PersonsGateway.CreatePerson(personVM);

        // Update view on DataGrid's itemssource collection
        ViewModel model = this.xGrid.DataContext as ViewModel;

        model.Persons.Insert(0, personVM);

XAML为:
<Window x:Class="OCDemo.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" xmlns:local="clr-namespace:OCDemo">
<Window.Resources>
    <local:ViewModel x:Key="xViewModel" />
</Window.Resources>
<Grid x:Name="xGrid" DataContext="{StaticResource xViewModel}">
    <DataGrid x:Name="xDataGrid" Grid.Row="0" ItemsSource="{Binding Persons}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=Name}" Header="Name"/>
            <DataGridTextColumn Binding="{Binding Path=Age}" Header="Age"/>
            <DataGridTextColumn Binding="{Binding Path=Address}" Header="Address"/>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

和ViewModel.cs
public class ViewModel
{
    public ObservableCollection<PersonViewModel> Persons { get; set; }

    public ViewModel()
    {
        this.Persons = PersonsGateway.RetrievePersons();
    }
}

T4 .tt文件已更新为MSDN - Updating code generation for data binding说明。

因此,在ObservableCollection场景中,可能仅依赖于将实体添加到数据库中,而不必始终将实体添加到itemssource集合中?

最佳答案

将您的 View 模型更改为以下内容

public class ViewModel
{
    public ObservableCollection<PersonViewModel> Persons { get; private set; }

    public ViewModel()
    {
        Persons = new ObservableCollection<PersonViewModel>();
        Persons.AddRange(PersonsGateway.RetrievePersons().ToList());
    }
}

重要的是,一次创建可观察的集合而不是重新创建它,而是依赖于更改通知,因此先创建它,然后使用标准方法来对其进行管理。

关于c# - 有没有一种方法可以使用ObservableCollection和MVVM刷新WPF DataGrid,而无需通知ItemsSource集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32784941/

相关文章:

c# - TimeZoneInfo.ConvertTime 从 PST 到 UTC 到 AEST - 关闭一小时

c# - 更改 DataGrid(WPF) 行中的单元格正在更改下方行中的单元格

c# - 单击搜索按钮触发验证

c# - View 模型的可见性不起作用

c# - 短暂延迟后消息框自动关闭

c# - 如何创建具有多个 XAML 文件的 WPF 应用程序?

c# - 在另一个线程 wpf 上创建 UI 重元素

c# - 如何在与 ItemsSource 绑定(bind)的 ListBox 中显示子元素的属性?

wpf - 将上下文菜单命令绑定(bind)到不在上下文视觉树中的 ViewModel

mvvm - 对于 Xamarin.Forms 中的 MVVM,哪个更好?共同观点还是平台特定观点?