新手尝试实现ICommand和MVVM [英] Newbie trying to implement ICommand and MVVM

查看:60
本文介绍了新手尝试实现ICommand和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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆