使用两个选定的组合框项目计算文本框

时间:2015-12-11 18:33:10

标签: c# wpf dynamic combobox

我的问题:我想在选择两个组合框变量后,将这两个变量分开并将文本框设置为计算结果。

两个组合框:Körpergröße& Gewicht

文本框:BMI

首先,代码我正在使用(显然现在不工作)

    private void fillTextBox(float value1, float value2)
   {
       BMI.Text = (value1 / value2).ToString();
   }

    private void Körpergröße_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        float a;
        float b;
        //In this way you can compare the value and if it is possible to convert into an integer. 
        if (float.TryParse(Körpergröße.SelectedItem.ToString(), out a) && float.TryParse(Gewicht.SelectedItem.ToString(), out b))
        {

            fillTextBox(a, b);
        }


    }

    private void Gewicht_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        float a;
        float b;
        //In this way you can compare the value and if it is possible to convert into an integer. 
        if (float.TryParse(Körpergröße.SelectedItem.ToString(), out a) && float.TryParse(Gewicht.SelectedItem.ToString(), out b))
        {

            fillTextBox(a, b);
        }
    }

两个组合框的默认值是字符串..(“Bitteususwählen”)

图片现在的样子。选择两个int值后,计算结果应显示在BMI文本框中,但仍为空白。它看起来像ToString()方法不保存到a,也没有保存到b ..因此值不能在fillTextBox方法中使用

enter image description here

如果有人能用一些附注的代码回答我,那将是很好的,以便我理解..

提前致谢!

1 个答案:

答案 0 :(得分:1)

以下是如何在WPF中编写一个简单的BMI计算器的示例。这是XAML的使用方式:所有逻辑都在View Model类BMIViewModel中。 View(XAML文件)围绕该逻辑包装UI。仅当您需要提供视图本身特有的一些特殊逻辑时,才使用代码隐藏文件。通常它根本不使用。在这里,没有使用它。

这与你可能习惯的方式有很大的不同,它在很多方面都是一个陡峭的学习曲线,但我已经学会了非常喜欢它。如果在各种视图模型中将程序逻辑分解为合理的块,则可以以各种不同的方式在UI中呈现这些视图模型。你获得了巨大的自由和力量。一旦获得了经过调试和测试的View Model,您就可以为它编写新的UI而无需触及程序逻辑。

如果您学习并理解此代码,您将有一个基本但坚实的基础来开始学习XAML。绑定很重要,OnPropertyChanged非常重要:该通知是视图模型如何让绑定知道值已更改。

我不喜欢为初学者编写这么多代码,但是你的代码(不是你的代码 - 它完全是从对这个问题的前一次迭代的错误答案中复制而来)是无法使用的。

XAML:

<Window 
    x:Class="TestApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestApplication"
    Title="MainWindow" Height="350" Width="525"
    >
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <StackPanel Orientation="Vertical">
            <StackPanel.Resources>
                <Style x:Key="FieldLabel" TargetType="Label">
                    <Setter Property="Width" Value="120" />
                </Style>
                <Style TargetType="ComboBox">
                    <Setter Property="Width" Value="140" />
                </Style>
                <Style TargetType="TextBox">
                    <Setter Property="Width" Value="140" />
                </Style>
            </StackPanel.Resources>
            <StackPanel Orientation="Horizontal">
                <Label Content="Height" Style="{StaticResource FieldLabel}" />
                <ComboBox 
                    ItemsSource="{Binding Heights}"
                    DisplayMemberPath="Name"
                    SelectedValuePath="Value"
                    SelectedValue="{Binding Height}"
                    />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="Weight" Style="{StaticResource FieldLabel}" />
                <ComboBox 
                    ItemsSource="{Binding Weights}"
                    DisplayMemberPath="Name"
                    SelectedValuePath="Value"
                    SelectedValue="{Binding Weight}"
                    />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="BMI" Style="{StaticResource FieldLabel}" />
                <TextBox IsReadOnly="True" Text="{Binding BMI}" />
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

后面的C#代码(我这里根本没有添加任何代码):

using System;
using System.Windows;

namespace TestApplication
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

BMIViewModel.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace TestApplication
{
    public class BMIListItem
    {
        public BMIListItem(string name, float value)
        {
            Name = name;
            Value = value;
        }
        public BMIListItem(float value)
        {
            Name = value.ToString();
            Value = value;
        }
        public String Name { get; set; }
        public float Value { get; set; }
    }

    public class BMIViewModel : INotifyPropertyChanged
    {
        public BMIViewModel()
        {
            //  Of course you would write loops for these in real life.
            //  You should not need help with that. 
            Heights = new List<BMIListItem>
            {
                new BMIListItem("Bitte auswählen", float.NaN),
                new BMIListItem("Dummy", 0),
                new BMIListItem(150),
                new BMIListItem(151),
                new BMIListItem(152),
                //  etc. 
            };
            Weights = new List<BMIListItem>
            {
                new BMIListItem("Bitte auswählen", float.NaN),
                new BMIListItem("Dummy", 0),
                new BMIListItem(40),
                new BMIListItem(41),
                new BMIListItem(42),
                //  etc.
            };
        }

        public List<BMIListItem> Heights { get; private set; }
        public List<BMIListItem> Weights { get; private set; }

        #region BMI Property
        private float _bmi = 0;
        public float BMI
        {
            get { return _bmi; }
            set
            {
                if (value != _bmi)
                {
                    _bmi = value;
                    OnPropertyChanged("BMI");
                }
            }
        }
        #endregion BMI Property

        #region Height Property
        private float _height = float.NaN;
        public float Height
        {
            get { return _height; }
            set
            {
                if (value != _height)
                {
                    _height = value;
                    UpdateBMI();
                    OnPropertyChanged("Height");
                }
            }
        }
        #endregion Height Property

        #region Weight Property
        private float _weight = float.NaN;
        public float Weight
        {
            get { return _weight; }
            set
            {
                if (value != _weight)
                {
                    _weight = value;
                    UpdateBMI();
                    OnPropertyChanged("Weight");
                }
            }
        }
        #endregion Weight Property

        private void UpdateBMI()
        {
            if (float.IsNaN(Weight) || float.IsNaN(Height) || Height == 0)
            {
                BMI = 0;
            }
            else
            {
                BMI = Weight / Height;
            }
        }

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(String propName)
        {
            var handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propName));
            }
        }
        #endregion INotifyPropertyChanged
    }
}