2012-01-30 75 views
3

我有一個Compact Framework(3.5)控件,我希望它具有默認顏色SystemColors.Window,與編輯控件相似。我遇到的問題是Visual Studio(2008)總是使用默認的BackColorControl來渲染設計圖面上的控件。我假設它要麼從基礎Control的默認背景顏色,父項或Site中拉出。如何在自定義的CF控件中重寫Ambient BackColor

任何人都有任何想法如何指定或以其他方式通知Visual Studio默認的BackColor應該是什麼?

public class MoneyInput : Control 
{ 

    public MoneyInput() 
    {    
     base.BackColor = SystemColors.Window; 
     base.ForeColor = SystemColors.WindowText; 
    } 

    public override Color BackColor 
    { 
     get 
     { 
      return base.BackColor; 
     } 
     set 
     { 
      base.BackColor = value; 
      Repaint();     
     } 
    } 

} 

這裏是我的DesignTimeAttributes.xmta文件的相應部分。請注意,我真的不希望默認的顏色爲白色,你看下面,我只是試圖讓什麼工作:

<DesktopCompatible>true</DesktopCompatible> 

<Property Name="BackColor"> 

    <Browsable>true</Browsable> 

    <DesignerSerializationVisibility> 
    DesignerSerializationVisibility.Visible 
    </DesignerSerializationVisibility> 

    <DefaultValue> 
    <Type>System.Drawing.Color</Type> 
    <Value>System.Drawing.Color.White</Value> 
    </DefaultValue> 

    <Category>Appearance</Category> 

    <Description>The background color of the control</Description> 

</Property> 

只需添加更多一些進展(或缺乏),我在控件中添加了一個日誌,以便在設計界面上放下控件時可以看到發生了什麼。在構造函數中對BackColor的寫入確實生效,並將顏色從「控制」更改爲「窗口」。但是,然後設計器基礎設施中的某些東西將顏色(通過屬性)設置回Control。這發生在ctor之後但在OnResize和OnHandleCreated之前。現在,如果控件使用正確的值將BackColor屬性序列化到設計器中,那麼它將安全地返回,但設計器不包含默認值。

最後一次編輯,我認爲用於指定枚舉(而不是基本類型)的默認值語法不正確。我正在使用我在下面發佈的解決方案,但這是一種破解,希望下一個出現的人能夠真正解決它。

+0

你可以創建一個'OnShow'事件和色彩的控制呢? – jp2code 2012-01-31 19:22:55

+0

@ jp2code無法覆蓋的OnShow方法。 – tcarvin 2012-01-31 19:44:31

回答

0

我希望能得到一個真正的答案是,但我會在這裏放下我的工作,它的解決方案:

public class MoneyInput : Control 
{ 

    // workaround for colors 
    private bool _constructed = false; 
    private int _handlesCreated; 


    public MoneyInput() 
    { 
     this.BackColor = SystemColors.Window; 
     this.ForeColor = SystemColors.WindowText; 
     _constructed = true; 
    } 

    public override Color BackColor 
    { 
     get 
     { 
      return base.BackColor; 
     } 
     set 
     { 
      // The logic below is based on: 
      // 
      // 1. If not _constructed then we are getting called 
      //  from our ctor and we want the set to happen. 
      // 2. If we do not have a Handle yet then we are 
      //  getting called by the infrastructure that 
      //  creates a control. 
      // 3. At design-time, the VS designer applies the 
      //  Ambient color even if we explicitly set 
      //  our own color. It is supposed to only apply 
      //  the Ambient if we have not explictly set 
      //  a color. 
      // 4. At runtime we must accept any color changes 
      //  that are passed to us. 


      // see if VS designer is screwing with us 
      bool ignoreColorSet = 
       _constructed 
       && _handlesCreated == 0 
       && RunningInDesigner; 


      if (!ignoreColorSet) 
      { 
       base.BackColor = value; 
       Repaint(); 
      } 


     } 
    } 


    protected override void OnHandleCreated(EventArgs e) 
    { 
     _handlesCreated++; 
     base.OnHandleCreated(e);   
    } 

    private bool RunningInDesigner 
    { 
     get 
     { 
      // this control is mobile-only so if we are running on full 
      // windows we must be in design mode. Note that this works 
      // even if we are not Sited yet, where as checking the 
      // DesignMode property can't be done untl the control has 
      // a Site. 
      return (System.Environment.OSVersion.Platform == PlatformID.Win32NT 
       || System.Environment.OSVersion.Platform == PlatformID.Win32Windows); 
     } 
    } 

}  
+0

已經過去了一個月,我想這是一個很好的答案... – tcarvin 2012-03-07 20:33:53

相關問題