【问题标题】:Updating ComboBox ItemSource for bound child objects为绑定的子对象更新 ComboBox ItemSsource
【发布时间】:2016-12-23 11:33:45
【问题描述】:

我有一个包含 2 个表的数据库; tblContacttblPersontblContacttblPerson 之间存在一对多的关系——一个联系人可以有很多人。我正在使用 VB 2013 和实体框架来创建我的数据绑定。

我遇到的问题是绑定的 ComboBox (cboPerson),当我添加/删除/更改人员时不会更新,除非我移动到其他联系人然后返回。有没有刷新 ComboBox ItemSource 的方法。

我可以看到我所做的更改反映在底层对象和数据库中。

这是 XAML。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:TestBinding" mc:Ignorable="d" x:Class="MainWindow"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <CollectionViewSource x:Key="ContactView" d:DesignSource="{d:DesignInstance {x:Type local:tblContact}, CreateList=True}"/>
        <CollectionViewSource x:Key="PersonView" Source="{Binding tblPersons, Source={StaticResource ContactView}}" />
    </Window.Resources>

    <Grid DataContext="{Binding Source={StaticResource ContactView}}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Label Grid.Row="0" Margin="3" Grid.Column="0" Content="Contact ID:"/>
        <TextBox Grid.Row="0" Margin="3" Grid.Column="1" Padding="3" x:Name="txtContactID" VerticalAlignment="Center" Text="{Binding Contact_ID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />

        <Label Grid.Row="1" Grid.Column="0" Margin="3" Content="Person ID:" />
        <ComboBox Grid.Row="1" Grid.Column="1" Margin="3" Padding="3" x:Name="cboPerson" SelectedValue="{Binding Contact_Primary_Person}" ItemsSource="{Binding Source={StaticResource ContactView}, Path=tblPersons, Mode=TwoWay}" SelectedValuePath="Person_ID" DisplayMemberPath="Person_Salutation" />

        <StackPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" >
            <Button Margin="3" Padding="3" Name="btnAdd">Add</Button>
            <Button Margin="3" Padding="3" Name="btnPrev">Prev</Button>
            <Button Margin="3" Padding="3" Name="btnNext">Next</Button>
            <Button Margin="3" Padding="3" Name="btnDelete">Delete</Button>

        </StackPanel>
    </Grid>
</Window>

还有表单背后的代码。

    Imports System.Data.Entity
    Class MainWindow
        Dim _context As ct_dbContext
        Dim ContactView As System.Windows.Data.CollectionViewSource
        Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles MyBase.Loaded

        _context = New ct_dbContext

        ContactView = CType(Me.FindResource("ContactView"), System.Windows.Data.CollectionViewSource)
        'Load data by setting the CollectionViewSource.Source property:
        'TblContactViewSource.Source = [generic data source]

        _context.tblContacts.Load()

        ContactView.Source = _context.tblContacts.Local

    End Sub

    Private Sub btnAdd_Click(sender As Object, e As RoutedEventArgs) Handles btnAdd.Click

        Dim newPerson As New tblPerson With {.Person_Created = Now, .Person_Email = "test@cambertown.com", .Person_Forename = "Joe", .Person_Mobile = "07", _
                                             .Person_Phone = "01", .Person_Salutation = "Mr Smith", .Person_Surname = "Smith", .Person_Title = "Mr", .Person_Updated = Now}

        Dim currentContact As tblContact = ContactView.View.CurrentItem

        currentContact.tblPersons.Add(newPerson)

        _context.SaveChanges()

    End Sub

    Private Sub btnNext_Click(sender As Object, e As RoutedEventArgs) Handles btnNext.Click

        ContactView.View.MoveCurrentToNext()

    End Sub

    Private Sub btnPrev_Click(sender As Object, e As RoutedEventArgs) Handles btnPrev.Click
        ContactView.View.MoveCurrentToPrevious()
    End Sub

    Private Sub btnDelete_Click(sender As Object, e As RoutedEventArgs) Handles btnDelete.Click

    End Sub

End Class

任何建议或指示将不胜感激。

【问题讨论】:

  • 如果您发布的代码更少,它会有所帮助。只有与问题相关的代码才能使这个问题更容易回答,而不是必须遍历整个类。

标签: wpf vb.net entity-framework-6


【解决方案1】:

有没有刷新 ComboBox ItemSource 的方法。

您可以通过在其视图上调用 Refresh 方法来刷新 CollectionViewSource:

ContactView.View.Refresh()

另一种选择是将 CollectionViewSource 的 Source 设置为 ObservableCollection(Of tblPerson) 并记住在将新的 tblPerson 对象添加到该集合之前,以及将其添加到数据库中。

【讨论】:

  • 感谢您的回复,我在 _context.SaveChanges() 之后立即添加了这个,但它没有刷新到组合框的内容。我将研究更改为 ObservableCollection。
  • 将新项目添加到数据库时,tblContacts 集合的本地副本不会更改。您需要再次获取记录以更新 CollectionViewSource: ContactView.Source = _context.tblContacts.ToList();这就是为什么您应该使用 ObservableCollection 作为来源,并记住在更新数据库时也要向该来源添加任何新项目。
【解决方案2】:

如果您绑定到一个集合(例如您的组合框项目),如果您更改此集合中的单个项目,则此集合不会更新。这是因为您绑定的集合对象仍然相同(即使集合中的项目可能已更改)。您的控件不会收到更改通知,因为从未引发属性更改通知。当您更改为不同的联系人时,您实际上更改了整个对象,这会触发属性更改事件。当您开始对集合使用绑定时,这是一个相当常见的“问题”。

如果您希望集合在其中的值发生更改时通知您,最常见的解决方案是使用 ObservableCollection。这具有内置的属性更改通知。

如果对象是 EF 对象并且它们是为您创建的,那么您可以考虑安装 NuGet 包“propertychanged.fody”。这使您能够通过简单地设置 [ImplementPropertyChanged] 属性向任何类添加属性更改通知。

EF 类是部分类,因此这允许您创建第二个文件,然后您可以使用该文件向其中添加属性更改通知。

结果(添加 fody 后)将创建一个看起来像这样的文件(您需要添加名称空间等...);

[ImplementPropertyChanged]
public partial class tblContact
{
}

这就是你所要做的。 tblContact 的所有属性现在都将具有属性更改通知。您可能需要对您的人员类型执行相同的操作。

使用部分类是扩展设计器为您生成的 EF 类的行为的好方法。如果您是部分类的新手,它们是一种将类定义拆分为两个或多个文件的方法,因此尽管您不会编辑设计师为您构建的部分,但您可以在文件中做您想做的事情。部分类的名称显然需要相同,以便编译器知道它们实际上是同一个类。

【讨论】:

  • 感谢您的回复。我一直在考虑这个问题,但由于实体框架为我创建了对象,我不知道我需要更改什么才能使集合成为 ObervableCollection。我有几天很安静,所以我会看看 EF 创建的对象。
  • 感谢您的更新,我今天将探索这个。
【解决方案3】:

我找到了这个页面Entity Framework Databinding with WPF,并按照更新数据绑定代码生成标题下的说明进行操作。

我也必须添加

Imports System.Collections.ObjectModel

到生成的类 tblContact.vb。

现在,当我添加、删除和更新 tblPerson 时,组合框会自动更新。

【讨论】:

    猜你喜欢
    • 2013-06-09
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2017-01-05
    • 2016-03-12
    • 1970-01-01
    相关资源
    最近更新 更多