【问题标题】:Data Binding not working in WPF VB.NET数据绑定在 WPF VB.NET 中不起作用
【发布时间】:2013-03-19 05:14:01
【问题描述】:

我一直在尝试处理数据绑定,但无法使其正常工作。有人能指出我正确的方向吗?

我正在使用 VS2012 并在 WPF/vb.net 中进行编程。我有一个 xaml UI、一个更新属性的类和运行我的主循环的模块。我正在尝试根据模块中的动态数据更新 UI 中的文本块。

这是来自 UI 的重要 XAML:

<Page x:Class="pPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  xmlns:local="clr-namespace:BMI_WPF_v1"
  mc:Ignorable="d" 
  Title="BMI">

<Page.Resources>
    <local:clsItemGUI x:Key="clsitemgui" />
</Page.Resources>

<TextBlock x:FieldModifier="public" x:Name="p_force" Text="{Binding Path=Force, UpdateSourceTrigger=PropertyChanged}" />

这是我在主模块中调用以尝试更新 GUI:

Dim bmiUI As New clsItemGUI
bmiUI.UpdateForce(currentForce)

这是用于更新 GUI 的类:

Imports System.Collections.ObjectModel
Imports System.ComponentModel

Public Class clsItemGUI
Implements INotifyPropertyChanged

Private ForceValue As Double

Sub New()
End Sub

Public Sub UpdateForce(ByVal inputForce As String)
    Me.ForceValue = inputForce
End Sub

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Public Property Force() As Double
    Get
        Return ForceValue
    End Get
    Set(ByVal value As Double)
        ForceValue = value
        OnPropertyChanged("Force")
    End Set
End Property

Protected Sub OnPropertyChanged(ByVal name As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
End Sub

End Class

看起来我正在更新 ForceValue,但这并没有触发 UI 上的更新。显然我错过了一些愚蠢的东西,但我还没有偶然发现正确的资源。

【问题讨论】:

  • 我认为你需要将你的类设置为页面数据上下文而不是资源
  • 嗯,我以为我做到了?你能举例说明你的意思吗?

标签: wpf vb.net data-binding


【解决方案1】:

试试这个

在页面资源下添加datacontext

<Page.DataContext>

  <local:clsItemGUI/>

</Page.DataContext>

(模式=TwoWay)

<TextBlock x:FieldModifier="public" x:Name="p_force" Text="{Binding Path=Force, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

【讨论】:

  • 感谢 J King 的快速回复。现在文本块读取“0”(它曾经是空白的),但它仍然没有更新。我正在单步执行代码,我可以看到我正在将我的力变量传递给 Me.ForceValue。但是,我的两个断点: Return ForceValue 和 RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name)) ...从未达到。
【解决方案2】:

您必须将DataContext 分配给根布局(在我的示例中为Grid):

<Grid DataContext="{StaticResource clsitemgui}">
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="30" />
    </Grid.RowDefinitions>

    <TextBlock x:FieldModifier="public" x:Name="p_force" Text="{Binding Path=Force, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />   
    <Button x:Name="btn" Grid.Row="1" Content="Change" Click="Button_Click" />        
</Grid>

或者你可以在绑定的时候设置Source属性,像这样:

<TextBlock x:FieldModifier="public" x:Name="p_force" Text="{Binding Path=Force, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

UpdateForce 方法也有错误,您应该将新值分配给 Force 属性而不是 ForceValue 字段。当您将此值分配给字段 OnPropertyChanged 时,它不会被调用。

Public Class clsItemGUI
    Implements INotifyPropertyChanged

    Private ForceValue As Double

    Sub New()
        Force = 2.5
    End Sub

    Public Sub UpdateForce(ByVal inputForce As Double)
        Me.Force = inputForce
    End Sub

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Public Property Force() As Double
        Get
            Return ForceValue
        End Get
        Set(ByVal value As Double)
            ForceValue = value
            OnPropertyChanged("Force")
        End Set
    End Property

    Protected Sub OnPropertyChanged(ByVal name As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
    End Sub

End Class

当您更新时,您应该对分配为 DataContext 的当前对象执行此操作,因此您应该强制转换此对象并在其上调用 UpdateForce 函数:

Private Sub Button_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
    Dim dt As clsItemGUI
    dt = CType(btn.DataContext, clsItemGUI)
    dt.UpdateForce(5.2)
End Sub

【讨论】:

  • Kmatyaszek,我尝试了这两种更改,但我的 UI 仍然没有更新。然而,我现在在“Return ForceValue”上打断点——只有一次,当我第一次加载程序时(在 UI 出现之前)。
  • @gadget00 再次检查我的答案 :)
  • 啊!现在我们用煤气做饭。现在,当我单步执行代码时,我点击了 UpdateForce 函数,它触发了 Force() 属性函数,然后是 OnPropertyChanged 函数。但是,它仍然没有更新 UI。我的 UI 现在一直是 2.5。
  • 我相信 UI 只是冻结了,现在......但它应该在它自己的线程上运行,不是吗?回到 Windows 窗体(我更舒服)我会抛出一个 Application.DoEvents(),但我知道这不再是必要的。
  • @gadget00 我为你创建了一个简单的例子,你可以在这里下载:sdrv.ms/116B6Op
猜你喜欢
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
相关资源
最近更新 更多