简体   繁体   中英

Binding TextBoxes to a Button (MVVM)

I'm making an application to generate recipes for a specified period (for example a week). As part of this application I have to make a list of ingredients. These ingredients can be specified by the user so I made a UserControl for adding an ingredient. This UserControl contains 6 TextBox -es and a Button . What I'm trying to do is when the user click on the button, the ingredient specified by the user (and by the TextBoxes) will be added to the list of ingredients.

I'm using MVVM architecture and a MultiValueConverter to bind the TextBoxes to the Button. I noticed that the Convert method was called only at the instantiation, but not when I click the Button.

How can I solve this problem still using MVVM?

Thanks for your advice and time!

The corresponding code snippets:

AddIngredientView.xaml :

<UserControl.Resources>
        <ResourceDictionary>
            <converters:IngredientConverter x:Key="IngredientConverter"/>
        </ResourceDictionary>
</UserControl.Resources>
    
<StackPanel>
    <TextBlock Text="Étel hozzáadása" Foreground="White" FontSize="28" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,20"/>

    <TextBox Name="nameTextBox"         ToolTip="Név"            Width="250" Height="40" VerticalContentAlignment="Center" HorizontalAlignment="Center" Margin="5" Style="{StaticResource ModernTextbox}"/>
    <TextBox Name="weightTextBox"       ToolTip="Tömeg (g)"      Width="250" Height="40" VerticalContentAlignment="Center" HorizontalAlignment="Center" Margin="5" Style="{StaticResource ModernTextbox}"/>
    <TextBox Name="energyTextBox"       ToolTip="Energia (kcal)" Width="250" Height="40" VerticalContentAlignment="Center" HorizontalAlignment="Center" Margin="5" Style="{StaticResource ModernTextbox}"/>
    <TextBox Name="carbohydrateTextBox" ToolTip="Szénhidrát (g)" Width="250" Height="40" VerticalContentAlignment="Center" HorizontalAlignment="Center" Margin="5" Style="{StaticResource ModernTextbox}"/>
    <TextBox Name="proteinTextBox"      ToolTip="Fehérje (g)"    Width="250" Height="40" VerticalContentAlignment="Center" HorizontalAlignment="Center" Margin="5" Style="{StaticResource ModernTextbox}"/>
    <TextBox Name="fatTextBox"          ToolTip="Zsír (g)"       Width="250" Height="40" VerticalContentAlignment="Center" HorizontalAlignment="Center" Margin="5" Style="{StaticResource ModernTextbox}"/>

    <Button Content="További értékek" Foreground="#353340" FontSize="14" Margin="0,10,60,0">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="TextElement.FontFamily" Value="Fonts/#Poppins"/>
                <Setter Property="Background"             Value="DarkGray"/>
                <Setter Property="Cursor"                 Value="Hand"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#353340"/>
                        <Setter Property="Foreground" Value="DarkGray"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
        <Button.Template>
            <ControlTemplate TargetType="Button">
                <Border Width="130" Height="25" CornerRadius="12" Background="{TemplateBinding Background}">
                    <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Button.Template>
    </Button>
    <Button Content="Hozzáadás" Foreground="#353340" FontSize="14" Margin="500,50,0,0" Command="{Binding AddIngredientCommand}">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="TextElement.FontFamily" Value="Fonts/#Poppins"/>
                <Setter Property="Background" Value="DarkGray"/>
                <Setter Property="Cursor" Value="Hand"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="#353340"/>
                        <Setter Property="Foreground" Value="DarkGray"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
        <Button.Template>
            <ControlTemplate TargetType="Button">
                <Border Width="100" Height="25" CornerRadius="12" Background="{TemplateBinding Background}">
                    <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Button.Template>
        <Button.CommandParameter>
            <MultiBinding Converter="{StaticResource IngredientConverter}" UpdateSourceTrigger="PropertyChanged">
                <Binding Path="Text" ElementName="nameTextBox"/>
                <Binding Path="Text" ElementName="weightTextBox"/>
                <Binding Path="Text" ElementName="energyTextBox"/>
                <Binding Path="Text" ElementName="carbohydrateTextBox"/>
                <Binding Path="Text" ElementName="proteinTextBox"/>
                <Binding Path="Text" ElementName="fatTextBox"/>
            </MultiBinding>
        </Button.CommandParameter>
    </Button>
</StackPanel>

IngredientConverter.cs :

public class IngredientConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return String.Concat(values[0], ",", values[1], ",", values[2], ",", values[3], ",", values[4], ",", values[5]);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return (value as string).Split(',');
    }
}

AddIngredientViewModel.cs :

public class AddIngredientViewModel : ViewModelBase
{
    #region Fields

    private YazioRecipesAddOnModel _model;

    #endregion

    #region Properties

    public DelegateCommand AddIngredientCommand { get; private set; }

    #endregion

    #region Constructor

    public AddIngredientViewModel(YazioRecipesAddOnModel model)
    {
        _model = model;
        AddIngredientCommand = new DelegateCommand(param => AddIngredient(param.ToString()));
    }

    #endregion

    #region Public methods

    public void AddIngredient(String ingredientString)
    {
        if (ingredientString == null)
            return;

        _model.AddIngredient(ingredientString);
    }

    #endregion
}

You should bind each TextBox to a different source property of the view model eg:

<TextBox Name="weightTextBox" Text="{Binding Weight}" />

You could then simply access the values directly in your AddIngredient method:

string ingredientString = string.Concat(this.Weight, "," ...);
_model.AddIngredient(ingredientString);

One of the key aspects of MVVM is to implement the application logic in the view models. Don't use converters for this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM