外部包

时间:2016-07-25 15:44:20

标签: .net wpf polymorphism

在我的项目中,我为控件AutoCompleteTextBox(https://wpfautocomplete.codeplex.com/)添加了一个外部包。

我还有一个屏幕键盘。

每当用户点击文本框时,键盘会将此键盘分配给属性本身,并且每次单击数字都会将该数字添加到文本框中。

某些文本框必须自动完成,其他文本框必须是常用的TextBox。

这里的问题是AutoCompleteTextBox不会从TextBox继承,因此我无法创建一个唯一的"分配TextBox"用于键盘。但是两个控件共享属性" Text",这是我唯一需要使用的属性。

public partial class Keypad : UserControl
{
    private AutoCompleteTextBox _controlAsignado; //this should be a generic class or an interface
    public Keypad() { }
    public void AsignarControl(AutoCompleteTextBox control)
    {
        _controlAsignado = control;
    }
    private void button_Click(object sender, RoutedEventArgs e)
    {
       Button button = sender as Button;
       switch (button.CommandParameter.ToString())
           {
           case "BACK":
               if (_controlAsignado.Text.Length > 0)
                            _controlAsignado.Text = _controlAsignado.Text.Remove(_controlAsignado.Text.Length - 1);
               break;
           default:
               _controlAsignado.Text += button.Content.ToString();
               break;
           }
    }

}

拥有一个" ITextBox"真是太棒了。两个控制实施。

我知道我可以使用反射解决这个问题,但我想要一个优雅的解决方案。

Horas Maquina and Orden Servicio must be "TextBox", the rest are AutoCompleteTextBox

1 个答案:

答案 0 :(得分:2)

您可以为这两个类创建一个包装器(最好也使用ITextBox接口),这样您就可以抽象出差异并使用运行时多态性:

interface ITextBox { string Text {get; set;} }
abstract class TextWrapper<T>: ITextBox where T: Control {
    T Wrapped;
    TextWrapper(T textControl) {
        this.Wrapped = textControl;
    }
    Text{ get{
        return Wrapped.Text;
    }
    set (string value) {
        Wrapped.Text = value;
    } 
}
class TextBoxWrapper: TextWrapper<TextBox> {}
class AutoCompleteTextBoxWrapper: TextWrapper<AutoCompleteTextBox> {}

您的代码如下所示:

public partial class Keypad : UserControl
{
    private ITextBox _controlAsignado;
    public Keypad() { }
    public void AsignarControl(AutoCompleteTextBox control)
    {
        _controlAsignado = new AutoCompleteTextBoxWrapper(control);
    }
    private void button_Click(object sender, RoutedEventArgs e)
    {
       Button button = sender as Button;
       switch (button.CommandParameter.ToString())
           {
           case "BACK":
               if (_controlAsignado.Text.Length > 0)
                            _controlAsignado.Text = _controlAsignado.Text.Remove(_controlAsignado.Text.Length - 1);
               break;
           default:
               _controlAsignado.Text += button.Content.ToString();
               break;
           }
    }
}

(我没有对代码进行过测试,但我希望一般的想法是你所寻找的。)