l1pton17
l1pton17

Reputation: 454

ReactiveCommand with CanExecute on Int32 property

I have the next viewmodel and i use canSubmit observable for SubmitOrder command. Quantity property is binded to TextBox's text property. And when i input some text in TextBox it doesn't trigger canSubmit observable and command is still be enabled. Here is my viewmodel:

public class CreateOrderViewModel : ReactiveObject
{
    private int _quantity;
    public int Quantity
    {
        get { return _quantity; }
        set { this.RaiseAndSetIfChanged(ref _quantity, value); }
    }

    private ISymbol _selectedSymbol;

    public ISymbol SelectedSymbol
    {
        get { return _selectedSymbol; }
        set { this.RaiseAndSetIfChanged(ref _selectedSymbol, value); }
    }

    private BuySell _side;

    public BuySell Side
    {
        get { return _side; }
        set { this.RaiseAndSetIfChanged(ref _side, value); }
    }

    public ReactiveCommand<Unit, IOrderProcessor> SubmitOrder { get; }

    public CreateOrderViewModel(IOrderService orderService)
    {
        var canSubmit = this.WhenAnyValue(v => v.SelectedSymbol, v => v.Quantity,
            (symbol, quantity) => symbol != null && quantity > 0);

        SubmitOrder = ReactiveCommand.Create(
            () =>   orderService.SubmitOrder(CreateOrderFromParameters()),
            canSubmit);
    }

    private Order CreateOrderFromParameters()
    {
        return new Order
        {
            Quantity = Quantity,
            Symbol = SelectedSymbol,
            Side = Side
        };
    }
}

My XAML:

<TextBlock Grid.Row="0" Grid.Column="0"
           Text="{x:Static properties1:Resources.Quantity}"
           />
<TextBox Grid.Row="0" Grid.Column="1"
         Text="{Binding Quantity, UpdateSourceTrigger=PropertyChanged}"
         />

<TextBlock Grid.Row="0" Grid.Column="2"
           Text="{x:Static properties1:Resources.Symbol}"
           />
<ComboBox Grid.Row="0" Grid.Column="3"
          ItemsSource="{Binding Symbols}"
          DisplayMemberPath="Ticker"
          SelectedItem="{Binding SelectedSymbol}"
          />

<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="6"
            HorizontalAlignment="Left">
    <Button Content="{x:Static properties1:Resources.Submit}"
            Command="{Binding SubmitOrder}"
            />
</StackPanel>       

Upvotes: 1

Views: 191

Answers (1)

l1pton17
l1pton17

Reputation: 454

Solved my problem by using StringToNullableNumericConverter:

public class StringToNullableNumberConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var stringValue = value as string;

        if (stringValue == null) return value;

        if (targetType == typeof(int?))
        {
            int intValue;
            if (Int32.TryParse(stringValue, out intValue))
            {
                return intValue;
            }

            return null;
        }

        return value;
    }
}

With folowing viewmodel:

    private int? _quantity;
    public int? Quantity
    {
        get { return _quantity; }
        set
        {
            if (!value.HasValue || value <= 0)
            {
                SetError(nameof(Quantity), Resources.Properties.Resources.OrderQuantityMustBePositiveErrorMessage);
            }
            else
            {
                ClearErrors(nameof(Quantity));
                this.RaiseAndSetIfChanged(ref _quantity, value);
            }
        }
    }

Upvotes: 0

Related Questions