我设置时没有设置TextBox.Text属性?

时间:2012-06-30 13:17:21

标签: c# winforms

这是最奇怪的事情,因为它在某些代码中对我不起作用。下面的代码位于一个子类TextBox的类中(注意:我不知道它是否重要,但我将Text属性子类化为从私有字段_realText设置/获取)

在下面的代码中,第一个base.Text = this.RealText工作正常!我们也在它的方法MaskData()中设置它,它的工作原理!那么为什么世界上它在if(!field.isSecure)部分不起作用? (看看我的意思的日志)。我尝试在base.Text = temp之后添加Invalidate(),Update(),但这没有帮助。

代码:

    private void SetupTextInBox()
    {
        if (isInManualMode)
        {
            this.ReadOnly = false;
            base.Text = this.RealText;
        }
        else
        {
            this.ReadOnly = true;
            if (!field.IsSecure)
            {
                string temp = this.RealText;
                log.Info("This field is not secure so show it. field=" + field.Variable + " real='" + temp+"'");
                base.Text = temp;
                log.Info("text value='" + base.Text+"'");
                return;
            }
            else
            {
                MaskData();
            }
        }
    }

日志

2012-06-30 07:15:51,468 [1] INFO  AlpineAccess.Plugins.SecureTalkPlugin.SecureTextControl (null) - This field is not secure so show it. field=1.acc real='2222' 
2012-06-30 07:15:51,468 [1] INFO  AlpineAccess.Plugins.SecureTalkPlugin.SecureTextControl (null) - text value=''

编辑:请注意,此方法始终从同一个线程调用。它来自服务器通知,告诉我们按下其他地方的电话铃声,然后该线程调用BeginInvoke将其放入GUI /控制线程等等。

上面方法上游的

代码是

    public void AppendDTMFDigit(string digit)
    {
        log.Info("specified="+field.MaxSpecified+" someone appending dtmf digit on field=" + field.Variable+" fieldMax="+field.Max+" len="+RealText.Length);
        if (field.MaxSpecified && this.RealText.Length >= field.Max)
            return; //shortcut out since we can't exceed max digits

        BeginInvoke(new MethodInvoker(delegate()
        {
            this.RealText = this.RealText + digit;
            log.Info("new realtext=" + this.RealText);
            SetupTextInBox();
        }
        )); 
    }

更多信息:如果我更改所有客户端代码以停止使用Text属性并使用RealText属性,然后停止覆盖Text属性,那么它可以正常工作。 (显然我不希望这样,虽然现在我不能只是从我的控件更改为TextBox并且很容易返回,而不会更改许多指向RealText属性的客户端代码....唉,可能不得不忍受这一点。 ......似乎是某种奇怪的错误。

更多信息:让调试器踩到它,这很奇怪。

2件很奇怪的事情。

  1. 它进入吸气器,而不是设定器???
  2. 它进入MY Text属性而不是TextBox的Text属性。
  3. grrrrr,为什么会......听起来像是一个主要的错误,对吧?我的意思是,base.Text应该引用超类的基础,对吗? - Dean Hiller刚刚编辑

    添加Text方法属性代码

        public override string Text
        {
            get
            {
                return RealText;
            }
            set
            {
                if (value == null)
                    throw new ArgumentException("Not allowed to set RealText to null.  Set to empty string instead");
                RealText = value;
            }
        }
    

2 个答案:

答案 0 :(得分:1)

除非您注释掉Text属性,否则此用户控件的完整源代码不起作用(您必须使用RealText属性并将其公开给客户端,因为base.Text似乎不起作用正确)。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using log4net;
using IntraNext.Win32.Config;

namespace AlpineAccess.Plugins.SecureTalkPlugin
{

    public partial class SecureTextBox : TextBox
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(SecureTextControl));

        private static readonly Color COLOR_FOCUSED = Color.Yellow;
        private static readonly Color COLOR_FOCUSED_MANUALMODE = Color.PaleGreen;

        private FocusEvent focusListener;
        private Field field;
        private bool isInManualMode;
        private EventHandler textChanged;
        private string RealText;

        public SecureTextBox()
        {
            InitializeComponent();
            RealText = "";
        }

        internal void Initialize(Field field, FocusEvent focusList, EventHandler textChanged)
        {
            this.focusListener = focusList;
            this.textChanged = textChanged;
            this.field = field;

            this.Enter += new EventHandler(SecureTextBox_Enter);
            this.Leave += new EventHandler(SecureTextBox_Leave);
            this.TextChanged += new EventHandler(SecureTextBox_TextChanged);

            MenuItem mnuItemNew = new MenuItem();
            mnuItemNew.Text = "&Clear";

            //THIS textbox HAS a context menu ALREADY BUT here we assign a new context menu to
            //our text box to replace the old one which had cut, paste etc. that we don't want
            //the agent using...
            this.ContextMenu = new ContextMenu();
            this.ContextMenu.MenuItems.Add(mnuItemNew);

            mnuItemNew.Click += new EventHandler(clear_Click);

            SwitchModes();
        }

        void SecureTextBox_TextChanged(object sender, EventArgs e)
        {
            if(isInManualMode) //make sure if in manual mode, we keep changes up to date in realText field
                RealText = Text;
            textChanged(sender, e);
        }

        void clear_Click(object sender, EventArgs e)
        {
            ClearAll();
        }

        internal void SetManualMode(bool inManual)
        {
            if (isInManualMode == inManual)
                return; //we don't care if there is no change so return;

            isInManualMode = inManual;
            SwitchModes();
        }

        void SecureTextBox_Leave(object sender, EventArgs e)
        {
            log.Info("exiting=" + field.Variable);
            focusListener(field.Variable, false, this.RealText);
            BeginInvoke(new MethodInvoker(delegate()
            {
                ChangeBackground();
            }
            ));            
        }

        void SecureTextBox_Enter(object sender, EventArgs e)
        {
            log.Info("entering=" + field.Variable );
            focusListener(field.Variable, true, this.RealText);
            BeginInvoke(new MethodInvoker(delegate()
            {
                ChangeBackground();
            }
            ));
        }

        private void SwitchModes()
        {
            SetupTextInBox();
            ChangeBackground();
        }

        private void SetupTextInBox()
        {
            if (isInManualMode)
            {
                this.ReadOnly = false;
                base.Text = RealText;
            }
            else if (!field.IsSecure)
            {
                this.ReadOnly = true;
                string temp = RealText;
                base.Text = temp;
                Invalidate();
                log.Info("txt=" + base.Text + " temp=" + temp);
            }
            else //not manual mode and IsSecure so mask it and make it readonly
            {
                this.ReadOnly = true;
                MaskData();
            }
        }

        private void MaskData()
        {
            log.Debug("mask=" + this.field.NumBeginDigitsToMaskSpecified + " num=" + field.NumBeginDigitsToMask + " txtLen=" + RealText.Length);
            int numDigitsToMask = RealText.Length;
            if (this.field.NumBeginDigitsToMaskSpecified && this.field.NumBeginDigitsToMask < RealText.Length)
            {
                int numDigits = this.field.NumBeginDigitsToMask;
                string maskedPart = "".PadLeft(numDigits, '●');
                string unmasked = RealText.Substring(numDigits);
                string full = maskedPart + unmasked;
                base.Text = full;
            }
            else
            {
                log.Debug("masking all digits");
                base.Text = "".PadLeft(RealText.Length, '●');
            }
        }

        private void ChangeBackground()
        {
            if (isInManualMode)
                SetManualModeColor();
            else
                SetNonManualModeColor();
        }

        private void SetNonManualModeColor()
        {
            if (this.Focused)
                this.BackColor = COLOR_FOCUSED;
            else
                this.BackColor = Control.DefaultBackColor;
        }

        private void SetManualModeColor()
        {
            if (this.Focused)
                this.BackColor = COLOR_FOCUSED_MANUALMODE;
            else
                this.BackColor = Control.DefaultBackColor;
        }

        public void AppendDTMFDigit(string digit)
        {
            log.Info("manualmode="+isInManualMode+" specified=" + field.MaxSpecified + " someone appending dtmf digit on field=" + field.Variable + " fieldMax=" + field.Max + " len=" + RealText.Length);

            if (isInManualMode)
                return;
            else if (field.MaxSpecified && RealText.Length >= field.Max)
                return; //shortcut out since we can't exceed max digits

            BeginInvoke(new MethodInvoker(delegate()
            {
                RealText = RealText + digit;
                SetupTextInBox();
            }
            )); 
        }

        internal void ClearAll()
        {
            log.Info("Cleared textbox for =" + field.Variable);
            base.Text = "";
            RealText = "";
            SetError("");
        }

        public override string Text
        {
            get
            {
                return RealText;
            }
            set
            {
                if (value == null)
                    throw new ArgumentException("Not allowed to set RealText to null.  Set to empty string instead");
                RealText = value;
            }
        }

        /**
         * Set to "" to clear the error or set anything to make valid
         */
        public void SetError(string error)
        {
            if (!this.IsHandleCreated)
                return;

            SecureTextBox box = this;
            //set to "" to clear the error
            BeginInvoke(new MethodInvoker(delegate()
            {
                errorProvider1.SetError(box, error);
            }));
        }
    }
}

答案 1 :(得分:1)

好的,你已经覆盖了文本 - 你可以在其中一行上找到它:

RealText = Text;

这将调用派生最多的'Text'属性(因为你没有指定base)并且会在当前控件上调用你被覆盖的'Text'

这意味着您将RealText设置为自身

e.g。

 void SecureTextBox_TextChanged(object sender, EventArgs e)
 {
     if (isInManualMode) //make sure if in manual mode, we keep changes up to date in realText field
     RealText = Text; <---- **THIS CALLS THE OVERIDDEN 'Text' BELOW**

     ... snip

来电

public override string Text 
{
    get { return RealText; }
}

哪一点......坚果!

你的意思是:

 void SecureTextBox_TextChanged(object sender, EventArgs e)
 {
     if (isInManualMode) //make sure if in manual mode, we keep changes up to date in realText field
     RealText = base.Text; <--- THIS?

仔细检查您的代码,我敢打赌这是您的问题之一

另外,稍微更改一下命名约定可能会有用......例如我倾向于使用下划线表示私有/受保护字段

private string _realText;

而不是属性的大写

private string RealText;

通常不公开公共字段,通常使用属性但是当我这样做时,我倾向于使用与属性相同的外壳

这样可以更容易区分代码中的属性和字段,并使调试更容易