Question

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

Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top