新手尝试实现ICommand和MVVM [英] Newbie trying to implement ICommand and MVVM
问题描述
某些背景...我对.Net编程世界还很陌生.我们的商店具有VB技能,所以我们要从VB6向前迈进VB.net ...我知道,还很遥远.无论如何,我正在以MVVM作为模式进行WPF和VB.net.一世 确实感觉我应该使用的代码应该工作,但是当然不是,这就是为什么我在这里.我一定想念一些小东西.因此,如果有人可以告诉我为什么这行不通,我将不胜感激.
Some background... I'm fairly new to the .Net world of programming. Our shop has VB skill sets so we are going VB.net as we move forward from VB6... i know, way behind. Anyway, I'm doing WPF and VB.net, with MVVM as the pattern. I really feel like the code I have should be working but of course it is not, thus why I am here. I must be missing some little piece. So if anyone can tell me why this doesn't work, I would be truly grateful.
MainWindow.xaml
MainWindow.xaml
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Configurator="clr-namespace:Configurator"
Title="MainWindow" Height="440" Width="886" WindowState="Maximized">
<Window.DataContext>
<Configurator:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="856*" />
</Grid.ColumnDefinitions>
<StackPanel Height="34" HorizontalAlignment="Stretch" Name="StackPanel1" VerticalAlignment="Top" Orientation="Horizontal" Panel.ZIndex="100" Margin="3,0,-3,0" Grid.ColumnSpan="2">
<StackPanel.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#4B000000" Offset="1" />
<GradientStop Color="White" Offset="0" />
<GradientStop Color="#FF969696" Offset="0.953" />
</LinearGradientBrush>
</StackPanel.Background>
<Label Content="Message Label" Height="28" Name="Label1" Width="846" />
<Button Content="X" Height="23" Name="Button1" Width="Auto" HorizontalAlignment="Right" />
</StackPanel>
<Label Content="NTC Job Data Configurator" Height="28" HorizontalAlignment="Center" Name="Label2" VerticalAlignment="Top" Grid.Column="1" Margin="0,35,0,0" />
<StackPanel Grid.Column="1" Height="100" HorizontalAlignment="Center" Margin="0,75,0,0" Name="StackPanel2" VerticalAlignment="Top" Width="200">
<Label Content="Job" Height="28" Name="Label3" HorizontalAlignment="Center" Margin="0,5,0,0" FontWeight="Bold" FontSize="14" />
<TextBox Text="{Binding Path=JobNumber, Mode=TwoWay}" Height="23" Name="TextBox1" Width="120" Margin="0,5" />
<Button Command="{Binding Path=CallSeasonTickets }" Content="Open" Height="23" Name="Button2" Width="75" Margin="0,5,0,0" />
</StackPanel>
</Grid>
</Window>
如果您查看底部,则会看到该按钮绑定到CallSeasonTickets,该代码位于以下代码中....
If you look at the bottom you'll see the button is bound to CallSeasonTickets which is in the following code....
Imports Configurator.MVVM
Public Class MainWindowViewModel
Inherits ViewModelBase
Private _jobNumber As String
Private _mSeasonTickets As ICommand
Public Property JobNumber() As String
Get
Return _jobNumber
End Get
Set(value As String)
_jobNumber = value
OnPropertyChanged("JobNumber")
End Set
End Property
Public Property CallSeasonTickets() As ICommand
Get
If (_mSeasonTickets Is Nothing) Then
_mSeasonTickets = New DelegateCommand(AddressOf SeasonTickets, AddressOf CanSeasonTickets)
End If
Return _mSeasonTickets
End Get
Set(value As ICommand)
End Set
End Property
Public Sub New()
JobNumber = ""
End Sub
Public Sub SeasonTickets(ByVal parm As Object)
Dim stViewModel = New SeasonTicketsViewModel(JobNumber)
Dim stWindow = New SeasonTicketsView
stWindow.DataContext = stViewModel
stWindow.Show()
End Sub
Public Function CanSeasonTickets(ByVal parm As Object) As Boolean
If JobNumber.Length = 0 Then
Return False
Else
Return True
End If
End Function
End Class
我有一个DelegateCommand.vb类
I have a DelegateCommand.vb class
Imports System.Windows.Input
Namespace MVVM
Public Class DelegateCommand
Implements ICommand
Private m_canExecute As Func(Of Object, Boolean)
Private m_executeAction As Action(Of Object)
Private m_canExecuteCache As Boolean
Public Event CanExecuteChanged(ByVal sender As Object, ByVal e As System.EventArgs) Implements ICommand.CanExecuteChanged
Public Sub New(ByVal executeAction As Action(Of Object), ByVal canExecute As Func(Of Object, Boolean))
Me.m_executeAction = executeAction
Me.m_canExecute = canExecute
End Sub
Public Function CanExecute(ByVal parameter As Object) As Boolean Implements ICommand.CanExecute
Dim temp As Boolean = m_canExecute(parameter)
If m_canExecuteCache <> temp Then
m_canExecuteCache = temp
RaiseEvent CanExecuteChanged(Me, New EventArgs())
End If
Return m_canExecuteCache
End Function
Public Sub Execute(ByVal parameter As Object) Implements ICommand.Execute
m_executeAction(parameter)
End Sub
End Class
End Namespace
该按钮不起作用.用于检查是否由于文本块为空而应该处于活动状态的验证不起作用,并且如果我可以单击该按钮,则不会打到我的SeasonTickets Sub.
The button is not working. The validation to check whether it should be active due to the textblock being empty or not doesn't work and if I can click the button then it doesn't hit my SeasonTickets Sub.
谢谢
布莱斯·马丁
推荐答案
尝试将CommandManager的RequerySuggested挂钩到CanExecuteChanged事件. (有关更多详细信息,请参见此处: http://joshsmithonwpf. wordpress.com/2008/03/18/understanding-routed-commands/#comment-10430 )
这是C#中的一个示例(将其转换回VB.NET并不难)
Here's an example in C# (shouldn't be too difficult to translate back to VB.NET)
public bool CanExecute(object parameter)
{
bool temp = canexec(parameter);
if (canexeccache != temp)
{
canexeccache = temp;
this._CanExecChanged(this, new EventArgs());
}
return canexeccache;
}
private event EventHandler _CanExecChanged;
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
this._CanExecChanged += value;
}
remove
{
this._CanExecChanged -= value;
CommandManager.RequerySuggested -= value;
}
}
这篇关于新手尝试实现ICommand和MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!