让两个变量相互映射

时间:2016-01-09 01:00:53

标签: c# class reference

class InputBox : TextBox
{
    private object value;

    protected override void OnLostFocus(EventArgs e)
    {
        base.OnLostFocus(e);

        try
        {
            value = TypeDescriptor.GetConverter(value.GetType()).ConvertFromString(Text);
        }
        catch (Exception e1)
        {
            Utils.offensiveMessage("Invalid format! This field accepts only " + value.GetType().Name + "!");
            Focus();
            Text = value.ToString();
        }          
    }

    public InputBox(object value) : base()
    {
        this.value = value;
        initializeComponent();
    }

    private void initializeComponent()
    {          
        Text = value.ToString();
    }
}

此类将此对象作为输入,将其表示为字符串,然后确保在文本框中写入的内容保持相同类型。关于它可以处理什么类型(仅限值类型)它有它的限制,但我在这些范围内工作。我为什么需要这个?

我有一个包含很多子类的大类,它们最终都包含值类型。我想要的是将这些数据呈现给用户并使他能够编辑它。这是我UI的一个原子。

这里有一个很棒的方法是让我在我的大类中的变量被上面显示的类中的变量镜像。当我在小班中改变一个时,大班中的那个以同样的方式改变。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

我会考虑使用Winforms Databinding - 如果您在大类上支持INotifyPropertyChanged,它会通过双向通知执行此操作。

但是,如果您因某些原因不想使用数据绑定,您可以将其视为替代方法,只需使您的代码正常工作:

public static class Program
{
    public static void Main()
    {
        var largeClass = new LargeClass() { Blah = 423 };
        var inputBox = new InputBox<double>(
            () => largeClass.Blah, 
            (a) => largeClass.Blah = a
            );
    }
}
public class LargeClass
{
    public double Blah { get; set; }
}
public class InputBox<T> : TextBox
{
    protected override void OnLostFocus(EventArgs e)
    {
        base.OnLostFocus(e);

        try
        {
            _setter((T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(Text));
        }
        catch (Exception e1)
        {
            //Utils.offensiveMessage("Invalid format! This field accepts only " + value.GetType().Name + "!");
            Focus();
            Text = _getter().ToString();
        }
    }

    private Func<T> _getter;
    private Action<T> _setter;

    public InputBox(Func<T> getter, Action<T> setter) : base()
    {
        _getter = getter;
        _setter = setter;

        InitializeComponent();
    }

    private void InitializeComponent()
    {
        Text = _getter().ToString();
    }
}

答案 1 :(得分:0)

我最终创建了一个实现了观察者模式类型接口的包装器。

包装对象确保偶数值类型作为引用传递(因为我现在传递的是包装器而不是值)。

我设置了观察者模式,以便观察到的包装对象可以通知任何观察者,然后相应地更新。