vb.net以编程方式添加绑定不起作用

时间:2016-05-05 13:11:44

标签: wpf vb.net xaml

我正在尝试将变量值绑定到按钮的content属性。我在XAML的主窗口的dockpanel中创建了一个名为“button”的按钮。

<Button x:Name="button" Content="Button" Height="100" 
                   VerticalAlignment="Top" Width="75"/>

然后我想以编程方式向公共变量test添加绑定。 初始值(400)在运行时正确显示,但是当我点击“NextTurn”按钮以引发Click事件时,绑定值不会更新。

Imports System.Windows.Data

    Class MainWindow

        Public test As Integer

        Public Sub New()

            InitializeComponent()

            Dim usr As New UserNS.User
            mainUser = usr
            test = 400
            Dim btest As New Binding()
            btest.Source = test
            button.SetBinding(Button.ContentProperty, btest)

        End Sub

 Private Sub NextTurn_Click(sender As Object, e As RoutedEventArgs) Handles NextTurn.Click

            test = test - 10

        End Sub
End Class

你能帮我吗?

非常感谢!

1 个答案:

答案 0 :(得分:1)

  1. 首先,不能绑定字段,只能绑定属性。
  2. 绑定源应该是一个具有您想要绑定的属性的对象 理想情况下,它不是表单类本身,而是一个单独的类(也就是视图模型) 例如。主窗口(名为MainWindow)可以具有名为MainViewModel的视图模型。
  3. 此对象必须实现INotifyPropertyChanged接口。
  4. 在属性设置器中,您必须调用一个方法,该方法会引发PropertyChanged接口附带的INotifyPropertyChanged事件。

    在我的例子中是:
    Private Sub NotifyPropertyChanged(...)

  5. 重要事项: VB.NET在不区分大小写的模式下工作,因此请避免将Button控件命名为button。此外,如果您实现完整属性,则支持字段应具有不同的名称。您不能同时拥有test字段和Test属性。这就是我为该字段选择_Test名称的原因。

    这是一个有效的例子:

    Imports System.ComponentModel
    Imports System.Runtime.CompilerServices
    
    Class MainWindow
        Implements INotifyPropertyChanged
    
        Public Sub New()
    
            ' Actually we can initialize the Test property here as well.
    
            ' This call is required by the designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
            Test = 400
    
            Dim bindingTest As New Binding() With {
                .Source = Me, ' The object which has the property we want to bind.
                .Mode = BindingMode.OneWay, ' We declare that the UI will accept changes from the object's property but not vica-versa.
                .Path = New PropertyPath("Test") 'We have to pass the name of the property as a String value.
            }
    
            TestButton.SetBinding(Button.ContentProperty, bindingTest)
    
            ' We could also initialize the Test property here.
    
        End Sub
    
        ' We can also initialize only the field instead of the property
        ' But new values must be set through the property setter.
        Private _Test As Integer
        Public Property Test() As Integer
            Get
                Return _Test
            End Get
            Set(ByVal value As Integer)
                _Test = value
                NotifyPropertyChanged()
            End Set
        End Property
    
        Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    
        ' We use CallerMemberName attribute so that we do not need to pass the name of the property.
        ' The compiler will automatically pass the name of the caller property. In our case: "Test"
        ' To get it work we declare the parameter as Optional so that we really do not have to pass a parameter value.
        Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = "")
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
        End Sub
    
        Private Sub NextTurnButton_Click(sender As Object, e As RoutedEventArgs)
            ' You must set the property's value instead of the backing field!
            Test = Test - 10
        End Sub
    
    End Class