RelayCommand работает в C#, но не в VB, если не создан в конструкторе ViewModel
Я попытался реализовать команду нажатия кнопки, используя команду mvvmlight relay, как описано на этой странице msdn. В основном сначала я реализовал в VB и C#, как показано ниже. Как вы можете видеть, коды почти одинаковы, но нажатие кнопки не работает в VB, если я не создаю RelayCommand в конструкторе в VB и не вызываю событие PropertyChanged в установщике свойства IsInProgress (закомментированная часть). Может кто-нибудь объяснить мне эту разницу между VB и C#? Я также добавил ссылку на тестовый проект. тестовый проект
XAML: (то же самое для VB и C#)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<ComboBox Grid.Column="0" Grid.Row="0" Height="20" Margin="20,50,20,0" ItemsSource="{Binding Path=Items}" DisplayMemberPath="Name"
IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedItem}" />
<Button Grid.Column="0" Grid.Row="1" Content="Update" Height="20" Margin="20,0" VerticalAlignment="Center" Command="{Binding UpdateClick}" />
</Grid>
VB вид Модель:
Public Class MainViewModel
Inherits NotifyUIBase
Private _IsInProgress As Boolean
Public Property IsInProgress() As Boolean
Get
Return _IsInProgress
End Get
Set(ByVal value As Boolean)
_IsInProgress = value
'RaisePropertyChanged("IsInProgress")
End Set
End Property
Private _Items As List(Of Item)
Public Property Items() As List(Of Item)
Get
Return _Items
End Get
Set(ByVal value As List(Of Item))
_Items = value
End Set
End Property
Private _selectedItem As Item
Public Property SelectedItem() As Item
Get
Return _selectedItem
End Get
Set(ByVal value As Item)
_selectedItem = value
End Set
End Property
Public Sub New()
_IsInProgress = False
GetData()
'_UpdateClick = New RelayCommand(Async Sub()
' If IsInProgress = True Then
' Exit Sub
' End If
' IsInProgress = True
' UpdateClick.RaiseCanExecuteChanged()
' Await Update(False)
' IsInProgress = False
' UpdateClick.RaiseCanExecuteChanged()
' End Sub, Function() Not IsInProgress)
End Sub
Private _UpdateClick As RelayCommand
Public ReadOnly Property UpdateClick() As RelayCommand
Get
Return If(_UpdateClick Is Nothing, New RelayCommand(Async Sub()
If IsInProgress = True Then
Exit Sub
End If
IsInProgress = True
UpdateClick.RaiseCanExecuteChanged()
Await Update(False)
IsInProgress = False
UpdateClick.RaiseCanExecuteChanged()
End Sub, Function() Not IsInProgress), _UpdateClick)
End Get
End Property
Private Sub GetData()
_Items = New List(Of Item)
_Items.Add(New Item With {.Name = "item1", .Value = "0"})
_Items.Add(New Item With {.Name = "item2", .Value = "1"})
RaisePropertyChanged("Items")
End Sub
Private Function Update(v As Boolean) As Task(Of Boolean)
Throw New NotImplementedException()
End Function
End Class
Модель представления C#
namespace testWPF
{
public class MainViewModel :NotifyUIBase
{
public bool IsinProgress { get; set; }
public MainViewModel()
{
IsinProgress = false;
GetData();
}
public List<Item> Items { get; set; }
public Item SelectedItem { get; set; }
private RelayCommand _UpdateClick;
public RelayCommand UpdateClick
{
get
{
return _UpdateClick
?? (_UpdateClick = new RelayCommand(
async () =>
{
if (IsinProgress )
{
return;
}
IsinProgress = true;
UpdateClick.RaiseCanExecuteChanged();
await Update();
IsinProgress = false;
UpdateClick.RaiseCanExecuteChanged();
},
() => !IsinProgress ));
}
}
private Task<bool> Update()
{
throw new NotImplementedException();
}
private void GetData()
{
Items = new List<Item>();
Items.Add(new Item
{
Name = "item1",
Value = "0"
});
Items.Add(new Item
{
Name = "item2",
Value = "1"
});
RaisePropertyChanged("Items");
}
}
}
Код позади XAML:
C#
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
VB
Public Class MainWindow
Public Sub New()
InitializeComponent()
Me.DataContext = New MainViewModel()
End Sub
End Class