要修改的 UserControl 命令 属性

UserControl Command to modify Property

在用户控件中,我试图获取命令来修改 属性。我有一个 IncrementValueCommand 和一个 Value 属性,我想在单击按钮时增加它们。按钮的 Command 绑定到 IncrementValueCommand 并且 Content 绑定到 Value 属性.

我尝试了两种方法来做到这一点,在这两种情况下,按钮都没有显示值递增..

第一种方法:值

的依赖性属性

XAML:

<UserControl x:Class="UserControl1"
             x:Name="root"
             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:WpfApp1"
             mc:Ignorable="d"
             d:DesignHeight="100"
             d:DesignWidth="200"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <Button Content="{Binding Path=Value}"
            Command="{Binding Path=IncrementValueCommand}" />

</UserControl>

后面的代码:

Public Class UserControl1

    Public Shared ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(Integer), GetType(UserControl1), New PropertyMetadata(1))

    Public Property IncrementValueCommand As ICommand

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        IncrementValueCommand = New RelayCommand(AddressOf IncrementValue)

    End Sub

    Public Property Value() As Integer
        Get
            Return GetValue(ValueProperty)
        End Get
        Set(value As Integer)
            SetValue(ValueProperty, value)
        End Set
    End Property

    Private Sub IncrementValue()
        Value += 1
    End Sub

End Class

第二种方法:INotify属性更改值

XAML:

<UserControl x:Class="UserControl2"
             x:Name="root"
             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:WpfApp1"
             DataContext="{Binding RelativeSource={RelativeSource Self}}"
             mc:Ignorable="d"
             d:DesignHeight="100"
             d:DesignWidth="200"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <Button Content="{Binding Path=Value}"
            Command="{Binding Path=IncrementValueCommand}" />

</UserControl>

后面的代码:

Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Public Class UserControl2
    Implements INotifyPropertyChanged

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Private _value As Integer = 1
    Public Property IncrementValueCommand As ICommand

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        IncrementValueCommand = New RelayCommand(AddressOf IncrementValue)

    End Sub

    Public Property Value() As Integer
        Get
            Return _value
        End Get
        Set(value As Integer)
            If _value <> value Then
                _value = value
                NotifyPropertyChanged()
            End If
        End Set
    End Property

    ' This method is called by the Set accessor of each property.  
    ' The CallerMemberName attribute that is applied to the optional propertyName  
    ' parameter causes the property name of the caller to be substituted as an argument.  
    Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

    Private Sub IncrementValue()
        Value += 1
    End Sub

End Class

我省略了 RelayCommand class,它是 ICommand 的标准实现。

任何帮助将不胜感激。


工作代码(感谢 Peter Duniho 的回答)

通过先创建 IncrementValueCommand 来调整代码隐藏构造函数:

Public Sub New()

    ' Add any initialization after the InitializeComponent() call? Nah
    IncrementValueCommand = New RelayCommand(AddressOf IncrementValue)

    ' This call is required by the designer.
    InitializeComponent()

End Sub

正如我所解释的 ,您尝试使用命令更新值的这个特定变体的问题是您正在初始化 IncrementValueCommand 属性 调用 class 构造函数中的 InitializeComponent() 之后。

InitializeComponent() 调用是设置到 属性 的绑定的地方,即 XAML 中的 Command="{Binding Path=IncrementValueCommand}"。进行该调用时,属性 仍具有其默认值 null

稍后为 属性 赋值时,因为 属性 是自动实现的 属性,该赋值不会导致 属性 -发生更改通知,因此永远不会更新绑定以反映新值。

您可以为 属性 实现 属性-更改通知,就像已经为 Value 属性 所做的那样,或者您可以(就像我早先建议)在构造函数中移动赋值,以便它发生在之前调用InitializeComponent而不是之后。