UserControl Команда для изменения свойства - PullRequest
1 голос
/ 23 сентября 2019

В пользовательском элементе управления я пытаюсь получить команду для изменения свойства.У меня есть свойства IncrementValueCommand и Value, которые я хочу увеличить при нажатии кнопки.Command кнопки привязано к IncrementValueCommand, а Content привязано к свойству Value.

Я попытался сделать это двумя способами, и в обоих случаях кнопка не отображаетсяПриращение значения ..

1-й подход: свойство зависимости для значения

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

2-й подход: INotifyPropertyChanged для значения

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которая является стандартной реализацией для ICommand.

Любая помощь будет принята с благодарностью.


Рабочий код (спасибо Питеру Дунихо за его ответ)

Настройте код позадиконструктор путем создания IncrementValueCommand first:

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

1 Ответ

1 голос
/ 24 сентября 2019

Как я объяснил в этом комментарии , проблема в этом конкретном варианте ваших попыток использовать команду для обновления значения заключается в том, что вы инициализируете IncrementValueCommand свойство после вызов InitializeComponent() в конструкторе класса.

В вызове InitializeComponent() устанавливается привязка к этому свойству, то есть Command="{Binding Path=IncrementValueCommand}" в вашем XAML.Когда этот вызов сделан, свойство все еще имеет его значение по умолчанию null.

Когда вы назначаете свойству значение позже, потому что свойство является автоматически реализуемым свойством, в этом назначении нет ничего, что могло бывызывать уведомление об изменении свойства, поэтому привязка никогда не обновляется, чтобы отразить новое значение.

Вы можете реализовать уведомление об изменении свойства для этого свойства, как это уже сделано для свойства Value.или вы можете (как я предлагал ранее) переместить присваивание в конструкторе так, чтобы оно происходило до вызова InitializeComponent вместо после.

...