0

Below you see the stackPanel where the user has to choose an option from the enum using radio buttons. So, CoffeeStrength is an enumeration and using a converter, I am able to set the right value.

<StackPanel Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Center">
    <Label FontWeight="Bold">Strength</Label>
    <RadioButton GroupName="Strength" IsChecked="{Binding Path=CoffeeStrength, Converter={StaticResource EnumToBool}, ConverterParameter=Weak}">Weak</RadioButton>
    <RadioButton GroupName="Strength" IsChecked="{Binding Path=CoffeeStrength, Converter={StaticResource EnumToBool}, ConverterParameter=Normal}">Normal</RadioButton>
    <RadioButton GroupName="Strength" IsChecked="{Binding Path=CoffeeStrength, Converter={StaticResource EnumToBool}, ConverterParameter=Strong}">Strong</RadioButton>
</StackPanel>

Below you see my button, which uses a custom class as CommandParameter. I would like to add the value above (CoffeeStrength) as an additional parameter in this command, instead of saving the value to CoffeeStrength in my ViewModel (see binding).

<Button Content="Cappuccino + sugar"
        Command="{Binding DrinkCommand}"
        Style="{StaticResource DrinkButton}">
     <Button.CommandParameter>
           local:DrinkCommandParameters Name="Cappuccino" Milk="False" Sugar="True"/>
     </Button.CommandParameter>
</Button> 

In other words, I would like to remove the CoffeeStrength property from my ViewModel and only pass it into DrinkCommand. Since I only need to know the value when the command is activated. Below you see the enum and the unneeded? property in the viewmodel. The setter is never used in the code, since the user decides the strength.

public enum Strength
    {
        Normal = 0, Weak, Strong
    }

private Strength _coffeeStrength;
    public Strength CoffeeStrength
    {
        get { return _coffeeStrength; }
        set { _coffeeStrength = value; RaisePropertyChanged(() => CoffeeStrength); }
    }

Is there a way to remove the CoffeeStrength property from the ViewModel and pass the value directly to the DrinkCommand in XAML?

Frogical
  • 175
  • 1
  • 2
  • 13
  • What problem did you encounter in adding `CoffeeStrength` to your `DrinkCommandParameters` class? I have absolutely no idea what you're getting at about "saving it to the viewmodel first", so you might also want to provide a much more clear and complete explanation of what you're trying to do. I think you may be leaving out a few steps. – 15ee8f99-57ff-4f92-890c-b56153 Nov 05 '19 at 14:11
  • There is no problem when adding CoffeeStrength to the DrinkCommandParameters. I can do ```local:DrinkCommandParameters Name="Cappuccino" Milk="False" Sugar="True" Strength={Binding CoffeeStrength}/>``` without having any issues. But what I'm looking for is a way to bind the value directly from the radio buttons to DrinkCommandParameters. Do you understand what I mean? @EdPlunkett – Frogical Nov 05 '19 at 14:18
  • Are you trying to say you want to bind `DrinkCommandParameters.CoffeeStrength` to the selected value of that radio button group? – 15ee8f99-57ff-4f92-890c-b56153 Nov 05 '19 at 14:20
  • @EdPlunkett yes – Frogical Nov 05 '19 at 14:21
  • You could [make that radio group a listbox, with a template](https://stackoverflow.com/a/805030/424129). However, because the list of potential items is fixed, the code you have now is the best way to do it. What's your objection to using a viewmodel property? – 15ee8f99-57ff-4f92-890c-b56153 Nov 05 '19 at 14:24
  • @EdPlunkett Not really an objection, but in my opinion you never need to know the coffeestrength only if you call the DrinkCommand. Why would you than save it in your viewmodel: and make it always accessible. – Frogical Nov 05 '19 at 15:06
  • @Frogical Hi, I think that the very reason the ViewModel exists is to store the state of the View. In this case, CoffeeStrength is part of the View's state, so there is nothing wrong in defining it within the ViewModel's code, according to the MVVM pattern. – Sasino Nov 05 '19 at 15:12
  • 2
    @Sasinosoft It would be much, much better to say the view exists to display and modify the state of the viewmodel. It's absolutely normal though to put a thing like this in the viewmodel. – 15ee8f99-57ff-4f92-890c-b56153 Nov 05 '19 at 15:17

1 Answers1

1

Yes it is possible. But for you can pass the value CoffeeStrength to the command you have to extend your DrinkCommandParameters class with a dependency property e.g. CoffeeStrength. I doubt that it's a better solution as just leave it in ViewModel.

So the solution would be:

  • extend your DrinkCommandParameters with a dependency property
  • set x:Name for each RadioButton
  • use MultiBinding with bindings to the each RadioButton e.g. via ElementName to set the dependency property for cofee strength.
  • Implement a class with IMultiValueConverter and use this converter in the MultiBinding

Then your XAML can look out nearly so:

<StackPanel Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Center">
    <Label FontWeight="Bold">Strength</Label>
    <RadioButton x:Name="rbWeak" GroupName="Strength" IsChecked="True">Weak</RadioButton>
    <RadioButton x:Name="rbNormal" GroupName="Strength" IsChecked="False">Normal</RadioButton>
    <RadioButton x:Name="rbStrong" GroupName="Strength" IsChecked="False">Strong</RadioButton>
</StackPanel>
<Button Content="Cappuccino + sugar" Command="{Binding DrinkCommand}" Style="{StaticResource DrinkButton}">
    <Button.CommandParameter>
        <local:DrinkCommandParameters Name="Cappuccino" Milk="False" Sugar="True">
            <local:DrinkCommandParameters.CofeeStrength>
                <MultiBinding Converter="{StaticResource YourCofeeStrengthMultiValueConverter}">
                    <Binding Path="IsChecked" ElementName="rbWeak"/>
                    <Binding Path="IsChecked" ElementName="rbNormal"/>
                    <Binding Path="IsChecked" ElementName="rbStrong"/>
                </MultiBinding>
            </local:DrinkCommandParameters.CofeeStrength>
        </local:DrinkCommandParameters>
    </Button.CommandParameter>
</Button>
Rekshino
  • 6,954
  • 2
  • 19
  • 44