2

最近、値が必須かどうかを強調できるバージョンのWindowsNumericUpDownコントロールを作成する必要がありました。コントロールの背面の色を変更してこれを行う必要がありました。これは簡単だと思いましたが、そうしようとすると、すべてのコントロールを完全に描画できないという奇妙な副作用があることがわかりました。

以下のコードを使用して、私はこれを見ています:

コントロールをWindowsフォームにドロップし、BackColorプロパティを(つまり、青に)変更すると、コントロールの数値部分全体の色が変わります。または、「IsMandatory」プロパティを変更した場合、すべての背面の色が変更されるわけではありません(境界線が残ります)。したがって、BackColorをBlueに変更してから、IsMandatoryをTrueに設定すると、青い境界線を持つLightBlueコントロール(必須の色)が得られます。

どちらも同じコードを使用しているので、なぜそうなのかわかりません。

アイデアや説明は大歓迎です。

   public partial class MyNumericUpDown : NumericUpDown
   {
      private Boolean _isMandatory = false;
      private Color _mandatoryBackColor = Color.LightBlue;
      private Color _backColor = Color.FromKnownColor(KnownColor.Window);

      [DefaultValue(typeof(Color), "Window"), Description("Overridden property")]
      override public Color BackColor
      {
         get { return _backColor; }
         set
         {
            _backColor = value;
            MyResetColors();
         }
      }

      [DefaultValue(typeof(Color), "LightBlue"), Category("Appearance")]
      public Color MandatoryBackColor
      {
         get {return _mandatoryBackColor;}
         set 
         {
            _mandatoryBackColor = value;
            MyResetColors();
         }
      }

      [DefaultValue(false), Category("Behavior")]
      public Boolean IsMandatory
      {
         get { return _isMandatory; }
         set
         {
            _isMandatory = value;
            MyResetColors();
         }
      }

      private void MyResetColors()
      {
         base.BackColor = (this.IsMandatory ? this.MandatoryBackColor : this.BackColor);
      }
   }

外観は次のとおりです。

4

3 に答える 3

2

興味深い質問ですが、仮想メンバーをオーバーライドすると予期しない副作用が発生する可能性があることを示しています。中心的な問題はBackColorプロパティゲッターです。IsMandatoryで別の値に強制した場合でも、常に_backColorプロパティ値を返します。このプロパティゲッターは、コントロールの背景を描画する必要がある場合にWinformsでも使用されます。したがって、スクリーンショットに青が表示される理由を説明する青を返します。

しかし奇妙なことに、それはコントロールのテキスト部分でも機能します。これは、NumericUpdownが複数のコントロールで構成されているためです。外側の境界を設定し、基本クラスであるContainerControlがあり、そのBackColorプロパティをオーバーライドしています。ただし、その中には、テキストを表示するTextBoxと上/下ボタンを表示するControlの2つのコントロールがあります。BackColorプロパティのオーバーライドは、 BackColorプロパティをオーバーライドしませ。したがって、テキストボックス部分は、Base.BackColorに割り当てた色で描画されます。

これを修正するには、BackColorについていじくり回すのをやめる必要があります。MandatoryColorではなく実際のBackColorがシリアル化されるように、これが設計時に引き続き機能することを確認する必要があるという追加の制約があります。

[DefaultValue(typeof(Color), "Window"), Description("Overridden property")]
override public Color BackColor {
    get {
        return base.BackColor;
    }
    set {
        _backColor = value;
        MyResetColors();
    }
}

private void MyResetColors() {
    base.BackColor = this.IsMandatory && !DesignMode ? this.MandatoryBackColor : _backColor;
}
于 2012-05-17T10:34:40.797 に答える
0

上記の方法は私にはうまくいきませんでした。私の回避策は次のとおりです。

    private void smartRefresh()
    {
        if (oldBackColor != BackColor) {
            oldBackColor = BackColor;
            Hide();
            Application.DoEvents();
            Show();
            Application.DoEvents();
        }
    }

プライベートメンバーoldBackColorを使用します。

これで、常に正しく表示されますが、ちらつきはありません。

補遺:コントロールの一部はまったくペイントされていないと思います(バグだと思います)。その周りの「塗り間違えた」ボスは均一に着色されていないため、以前そこにあったウィンドウの痕跡が見られることがあります。

于 2015-12-04T19:46:32.117 に答える
0

無効にすると、WindowsはNumericUpDownコントロールを適切に/完全に再描画しません。

この投稿を参照してください: 無効な要素のNumericUpDown背景色の変更

表示後にコントロールを有効/無効にすることは回避策です。

于 2017-11-15T13:23:38.393 に答える