سؤال

I've already done a lot of winform and many WPF(MVC style).

I've looked into the MVVM pattern, and for now, the only thing I'm stuck on is Commands.

The issue I got is that I don't find an adequate way to throw a command for many event.

I can't find how to invoke a command, that interaction on the Business context.

E.g. : I've the following MVVM model:

public class MyDemoViewModel : DependencyObject{
    private IDataManager _manager;
    private static readonly DependencyProperty _currentMessageDependancyProperty = DependencyProperty.Register("CurrentMessage", typeof(String), typeof(MyDemoViewModel), new PropertyMetadata(""));

    public ICommand SendMessageCommand{get; private set;}
    public String CurrentMessage {
            get { return(String) GetValue(_currentMessageDependancyProperty); }
            set { SetValue(_currentMessageDependancyProperty, value); }
        }

    public MyDemoViewModel(IDataManager manager){
        _manager= manager;
        SendMessageCommand = new SendMessageCommand(this);
    }

    public void SendMessage(String message){
        _manager.SendMessage(message);
        CurrentMessage = String.Empty;
    }
}

With a simple command:

public class SendMessageCommand :ICommand{
    private MyDemoViewModel _model;

    public SendMessageCommand(MyDemoViewModel model) {
        _model = model;
    }

    public event EventHandler CanExecuteChanged {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object parameter)
    {
        return !String.IsNullOrEmpty(_model.CurrentMessage);
    }

    public void Execute(object parameter)
    {
        _model.SendMessage( _model.CurrentMessage );
    }
}

And a basic XAML:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <TextBox Grid.Row="1" TextWrapping="Wrap" Text="{Binding CurrentMessage, UpdateSourceTrigger=PropertyChanged}"/>
    <Button Content="Send" Grid.Column="1"  Grid.Row="1" Command="{Binding SendMessageCommand}"/>
</Grid>

What should I do(I mean, in adequation with the MVVM pattern), to have my command executed when someone hit the Enter key in the TextBox? I mean, usually I would have set an event on "TextChanged" and send the command in the code behind. But I wan't to keep my code behind empty and without any knowledge of the model/business logic.

This is the most simple example that I've, but I can have the same kind of need for other operation(Operations that may not be accessible with a simple button).

Thank you

هل كانت مفيدة؟

المحلول

For your specific example, you can make use of InputBindings. These allow you to execute some command in reaction to gestures (usually keyboard or mouse). Here is a quick example to achieve what you are after:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <TextBox Grid.Row="1" TextWrapping="Wrap" Text="{Binding CurrentMessage, UpdateSourceTrigger=PropertyChanged}">
        <TextBox.InputBindings>
            <KeyBinding Command="{Binding SendMessageCommand}" Key="Return" />
            <KeyBinding Command="{Binding SendMessageCommand}" Key="Enter" />
        </TextBox.InputBindings>
    </TextBox>
    <Button Content="Send" Grid.Column="1"  Grid.Row="1" Command="{Binding SendMessageCommand}"/>
</Grid>

For more advanced situations, such as reacting to various UI events, you can make use of Expression Blends Interactivity namespace (see here):

<TextBox>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="GotFocus">
            <i:EventTrigger.Actions>
                <i:InvokeCommandAction Command="{Binding SendMessageCommand}" />
            </i:EventTrigger.Actions>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

An unofficial version of the Blend SDK can be found on NuGet here.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top