【问题标题】:How do I handle foreign keys with WPF databinding?如何使用 WPF 数据绑定处理外键?
【发布时间】:2008-10-12 06:20:59
【问题描述】:

我在 WPF 中有一个 ListView,它数据绑定到我从数据库中提取的基本表。 ListView的代码如下:

<ListView Canvas.Left="402" Canvas.Top="480" Height="78" ItemsSource="{Binding}" Name="lsvViewEditCardPrint" Width="419">
   <ListView.View>
      <GridView>
         <GridViewColumn DisplayMemberBinding="{Binding Path=IdCst}">Set</GridViewColumn>
         <GridViewColumn DisplayMemberBinding="{Binding Path=Language}">Language</GridViewColumn>
         <GridViewColumn DisplayMemberBinding="{Binding Path=Number}">Number</GridViewColumn>
         <GridViewColumn DisplayMemberBinding="{Binding Path=IdArt}">Artwork</GridViewColumn>
      </GridView>
   </ListView.View>
</ListView>

IdCst 列是单独表的外键,我想显示该表中的实际名称字段,而不仅仅是 Id。有谁知道如何设置数据绑定,或者是否有一个事件,例如 OnItemDataBound,我可以拦截以修改显示?

【问题讨论】:

    标签: wpf data-binding


    【解决方案1】:

    此博客post 可能会有所帮助:

    ...我假设外键应该绑定到“SelectedValue”属性, 并且有一个 ItemSource 我可以 绑定到我的事实表,所以下拉 已填充。

    此时我的下拉菜单有效,但是 组合框中不会出现任何内容。 我终于注意到了一个“SelectedItemPath” 财产 - 我认为这将是 我的下拉列表中的字段名称 与我的外键相关联。当然 够了,就是这样。

    【讨论】:

      【解决方案2】:

      我会为您的基础类添加一个新属性:

      Public ReadOnly Property NameCst() as String
          Get
              Return Names.LookupName(Me.IdCst)
          End Get
      End Property
      

      或类似的东西。请注意,您可能必须在“NameCst”的 .IdCst 设置器中包含 Notify Property Changed 事件。

      另一种方法是编写一个 ValueConverter 来进行查找,但对于如此简单的事情来说,这是相当沉重的。

      【讨论】:

        【解决方案3】:

        呸呸!!!

        我查看了这里的示例,从这里的其他帖子中挖掘了一些参考资料,并找到了答案... IValueConverter ... 一个可与 WPF 一起使用的接口,它将在绑定点转换值.一开始组装起来有点棘手,但没那么难。

        第一步是创建一个实现 IValueConverter 接口的简单查找或转换器类。对于我的解决方案,我这样做了:

        Namespace TCRConverters
        
           Public Class SetIdToNameConverter
              Implements IValueConverter
        
              Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
                 Dim taCardSet As New TCRTableAdapters.CardSetTableAdapter
                 Return taCardSet.GetDataById(DirectCast(value, Integer)).Item(0).Name
              End Function
        
              Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
                 Return Nothing
              End Function
        
           End Class
        
        End Namespace
        

        注意:我没有使用 ConvertBack 方法,但是接口需要它。

        您需要在 XAML 标头部分中添加对命名空间的引用:

        <Window x:Class="Main" Loaded="Main_Loaded"
            // Standard references here...
            xmlns:c="clr-namespace:TCR_Editor.TCRConverters"
            Title="TCR Editor" Height="728" Width="1135" Name="Main">
        

        然后在您的 Windows.Resources 部分中,您可以引用转换器,在我的例子中,我创建了一个对将存储数据的 CollectionViewSource 的静态引用:

        <Window.Resources>
           <CollectionViewSource Source="{Binding Source={x:Static Application.Current}, Path=CardDetails}" x:Key="CardDetails">         
           </CollectionViewSource>
        
           <c:SetIdToNameConverter x:Key="SetConverter"/>      
        </Window.Resources>
        

        最后,在作为初始问题一部分的 ListView 中,添加转换器引用:

        <ListView Canvas.Left="402" Canvas.Top="480" Height="78" ItemsSource="{Binding}" Name="lsvViewEditCardPrint" Width="419">
           <ListView.View>
              <GridView>
                 <GridViewColumn DisplayMemberBinding="{Binding Path=IdCst, Converter={StaticResource SetConverter}}">Set</GridViewColumn>
                 // Other Columns here...
              </GridView>
           </ListView.View>
        </ListView>
        

        所以现在最重要的是,当我触发具有 Card Id 的事件时,我需要做的就是重置 CollectionViewSource...

        DirectCast(Me.FindResource("CardDetails"), CollectionViewSource).Source = taCardDetails.GetDataById(CardId)
        

        ...以及 WPF 的所有绑定元素完成剩下的工作!

        好处是我可以轻松地创建其他转换器,将它们添加到应用程序中其他地方的各种 DataTemplate 或列中,一旦我将所有数据放入 WPF 应用程序本身,就可以进行转换到数据库。

        【讨论】:

        • 快速注释。我发现在添加所有 XAML 代码之前编译转换器类似乎有助于消除它会给您带来的一些“唠叨”,直到所有内容都编译在一起。
        • 很抱歉让您的泡沫破灭,但此转换器每行至少会访问数据库一次。
        • 确实如此。然而,目前这是针对填充一些查找代码的小集合。对于一些更大的工作,我肯定会做一些优化,或者一些本地缓存的数据,以尽量减少这种影响。但很高兴记住,谢谢。
        猜你喜欢
        • 2014-07-30
        • 1970-01-01
        • 2019-01-10
        • 2019-07-31
        • 1970-01-01
        • 1970-01-01
        • 2013-12-28
        • 2012-12-04
        • 1970-01-01
        相关资源
        最近更新 更多