单位换算器怎么做?

leon51 2019-07-08 09:18:23
想做一个长度、重量。。。单位换算器,每一个类型有10个左右文本框,要求在任一文本框中输入数值后,在其余文本框中列出相应的单位数值。之前用DataBindings代码很简练,但有一些细节问题始终无法克服,因此想换一个做法,但是没有思路。请问帮忙给点提示或启发?谢谢
...全文
154 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2019-07-09
  • 打赏
  • 举报
回复
引用 2 楼 wanghui0380 的回复:
1.你首先需要考虑,基准单位。比如时间大多数以秒记。(或者毫秒记) 2.需要考虑实现INotifyPropertyChange接口。 基本上有这两个就行。当然按照前贴的问题,还可以去实现IErrorInfo接口 我这里写个基本的样子
wanghui0380 2019-07-09
  • 打赏
  • 举报
回复
1.你首先需要考虑,基准单位。比如时间大多数以秒记。(或者毫秒记) 2.需要考虑实现INotifyPropertyChange接口。 基本上有这两个就行。当然按照前贴的问题,还可以去实现IErrorInfo接口 我这里写个基本的样子
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsFormsApp4.Annotations;


namespace WindowsFormsApp4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
           Vm vm=new Vm();
            this.textBox1.DataBindings.Add(nameof(textBox1.Text), vm, nameof(vm.米));
            this.textBox2.DataBindings.Add(nameof(textBox2.Text), vm, nameof(vm.厘米));
            this.textBox3.DataBindings.Add(nameof(textBox3.Text), vm, nameof(vm.毫米));
        }
    }

    public class Vm:INotifyPropertyChanged
    {
        //如果我已厘米为基准
        private double _厘米=0;
        private double _毫米=0;
        private double _米=0;

        public double 厘米
        {
            get => _厘米;
            set
            {
                if (value.Equals(_厘米)) return;
                _厘米 = value;
                OnPropertyChanged(); 
            }
        }

        public double 毫米
        {
            get => _毫米;
            set
            {
                if (value.Equals(_毫米)) return;
                _毫米 = value;
                this.厘米 = _毫米 / 10;
            }
        }

        public double 米
        {
            get => _米;
            set
            {
                if (value.Equals(_米)) return;
                _米 = value;

                this.厘米 = this._米 * 100;
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            //既然任何转换都会触发厘米,而厘米变化都会触发到此处,在此处重新整体计算
            this._毫米 = this.厘米 * 10;
            this._米 = this.厘米 / 100;
      
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
leon51 2019-07-09
  • 打赏
  • 举报
回复
以下是我的完整代码
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //双向绑定
            LengthConvert lengthConversion = new LengthConvert();

            Binding binding = new Binding("Text", lengthConversion, "M");
            binding.Format += Binding_Format;
            binding.Parse += Binding_Parse;
            binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
            txtM.DataBindings.Add(binding);

            binding = new Binding("Text", lengthConversion, "Dm");
            binding.Format += Binding_Format;
            binding.Parse += Binding_Parse;
            binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
            txtDm.DataBindings.Add(binding);


            binding = new Binding("Text", lengthConversion, "Cm");
            binding.Format += Binding_Format;
            binding.Parse += Binding_Parse;
            binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
            txtCm.DataBindings.Add(binding);

            binding = new Binding("Text", lengthConversion, "Mm");
            binding.Format += Binding_Format;
            binding.Parse += Binding_Parse;
            binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
            txtMm.DataBindings.Add(binding);
        }

        // Data -> UI 
        // Format 事件:当数据被绑定到控件的时候触发。就是在数据要显示到控件中的时候。
        private void Binding_Format(object sender, ConvertEventArgs e)
        {
            if (Convert.ToDouble(e.Value) == 0)
            {
                e.Value = "";
            }
        }


        // UI -> Data
        //Parse 事件:当控件的属性发生改变而导致要更新数据源的时候触发。
        private void Binding_Parse(object sender, ConvertEventArgs e)
        {
            if (e.Value.ToString().Trim() == "")
            {
                e.Value = 0;
            }
        }
    }
class LengthConvert
    {
        private double mm = 0;

        public double Mm
        {
            get { return Convert.ToDouble(mm); }
            set { mm = value; }
        }

        public double M
        {
            get { return Convert.ToDouble(mm) / 1000; }
            set { mm = value * 1000; }
        }

        public double Dm
        {
            get { return Convert.ToDouble(mm) / 100; }
            set { mm = value * 100; }
        }

        public double Cm
        {
            get { return Convert.ToDouble(mm) / 10; }
            set { mm = value * 10; }
        }
    }
leon51 2019-07-09
  • 打赏
  • 举报
回复
引用 2 楼 wanghui0380 的回复:
1.你首先需要考虑,基准单位。比如时间大多数以秒记。(或者毫秒记) 2.需要考虑实现INotifyPropertyChange接口。 基本上有这两个就行。当然按照前贴的问题,还可以去实现IErrorInfo接口 我这里写个基本的样子
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsFormsApp4.Annotations;


namespace WindowsFormsApp4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
           Vm vm=new Vm();
            this.textBox1.DataBindings.Add(nameof(textBox1.Text), vm, nameof(vm.米));
            this.textBox2.DataBindings.Add(nameof(textBox2.Text), vm, nameof(vm.厘米));
            this.textBox3.DataBindings.Add(nameof(textBox3.Text), vm, nameof(vm.毫米));
        }
    }

    public class Vm:INotifyPropertyChanged
    {
        //如果我已厘米为基准
        private double _厘米=0;
        private double _毫米=0;
        private double _米=0;

        public double 厘米
        {
            get => _厘米;
            set
            {
                if (value.Equals(_厘米)) return;
                _厘米 = value;
                OnPropertyChanged(); 
            }
        }

        public double 毫米
        {
            get => _毫米;
            set
            {
                if (value.Equals(_毫米)) return;
                _毫米 = value;
                this.厘米 = _毫米 / 10;
            }
        }

        public double 米
        {
            get => _米;
            set
            {
                if (value.Equals(_米)) return;
                _米 = value;

                this.厘米 = this._米 * 100;
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            //既然任何转换都会触发厘米,而厘米变化都会触发到此处,在此处重新整体计算
            this._毫米 = this.厘米 * 10;
            this._米 = this.厘米 / 100;
      
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
非常感谢你的回复,但是你的代码似乎编译不了,wpf中也不行。 实际上,我之前也是用的绑定,见下面这个帖子。正是同样在你的帮助下实现的: https://bbs.csdn.net/topics/392744992 但是这种写法有一个问题是,我希望文本框的值改变时其它文本框的值随之改变,因此将DataSourceUpdateMode设置为OnPropertyChanged,这样输入任一个整数都非常完美,但是输入小数的时候光标会跳到前面去...,我以为是Format和Parse事件的原因,或许是其中的代码不对?但是将代码注释掉仍有问题,如果能解决这个问题,一切都解决了
wilson1966 2019-07-09
  • 打赏
  • 举报
回复
用TextChanged 事件不行吗?

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧