2016-03-12 23 views
1

我遇到了一些我想升級的遺留代碼。我想改變ErrorProvider在控件上顯示錯誤狀態的方式。如果您將鼠標懸停在圖標上,默認行爲是圖標,並且有一個ToolTipErrorProvider - 更改BackColor而不是顯示圖標

我想將此行爲更改爲與我們在WPF控件中使用的行爲更類似。這是一個紅色的背景色(鮭魚粉紅色)和控制本身的工具提示。

任何提示,鏈接或某種方式前進

編輯。 看到我的答案在下面,我結束了。

+0

謝謝您的反饋意見。代碼現在發佈爲答案。再次感謝@ Reza-Aghaei – schultz

回答

1

ErrorProvider組件不支持此功能,如果您需要它,您可以自己創建它。

您可以訂閱BindingComplete事件BindingManagerBase的,然後你可以使用事件ARG它是一個包含了一些有用的特性BindingCompleteEventArgs類型:

  • ErrorText,以確定是否存在錯誤數據綁定
  • Binding.Control,以確定哪些爲界,

這些都足以讓我們實現我們的解決方案的控制。

代碼

這裏是一個示例代碼,說明如何處理BindingComplete事件,並用它來改變BackColor和基於它的有效或無效狀態的控制的工具提示。

假設您有一個綁定源myBindingSource,該綁定源綁定到實施IDataErrorInfoSampleModel類。您可以訂閱BindingComplete事件的this.BindingContext[this.myBindingSource]

private void Form1_Load(object sender, EventArgs e) 
{ 
    this.myBindingSource.DataSource = new SampleModel(); 

    var bindingManager = this.BindingContext[this.myBindingSource]; 
    bindingManager.BindingComplete += bindingManager_BindingComplete; 
} 

Dictionary<Control, Color> Items = new Dictionary<Control, Color>(); 
private void bindingManager_BindingComplete(object sender, BindingCompleteEventArgs e) 
{ 
    var control = e.Binding.Control; 
    //Store Original BackColor 
    if (!Items.ContainsKey(control)) 
     Items[control] = control.BackColor; 

    //Check If there is an error 
    if (!string.IsNullOrEmpty(e.ErrorText)) 
    { 
     control.BackColor = Color.Salmon; 
     this.errorToolTip.SetToolTip(control, e.ErrorText); 
    } 
    else 
    { 
     e.Binding.Control.BackColor = Items[e.Binding.Control]; 
     this.errorToolTip.SetToolTip(control, null); 
    } 
} 
1

謝謝禮Aghaei。這是我想出了基於您的意見和一些額外的搜索......這段代碼的一些來自msdn resource

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.ComponentModel.Design; 
using System.Drawing; 
using System.Linq; 
using System.Security.Permissions; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace ErrorProvider 
{ 
    class BackgroundColorErrorProvider: Component, IExtenderProvider, ISupportInitialize 
    { 

     public BackgroundColorErrorProvider() 
     { 
      currentChanged = new EventHandler(ErrorManager_CurrentChanged); 
     } 
     public BackgroundColorErrorProvider(ContainerControl parentControl) 
      : this() 
     { 
      this.parentControl = parentControl; 
      propChangedEvent = new EventHandler(ParentControl_BindingContextChanged); 
      parentControl.BindingContextChanged += propChangedEvent; 
     } 
     public BackgroundColorErrorProvider(IContainer container) 
      : this() 
     { 
      if (container == null) { 
       throw new ArgumentNullException("container"); 
      } 

      container.Add(this); 
     } 

     public bool CanExtend(object extendee) 
     { 
      return extendee is Control && !(extendee is Form) && !(extendee is ToolBar); 
     } 

     private bool inSetErrorManager = false; 
     private object dataSource; 
     private string dataMember = null; 
     private ContainerControl parentControl; 
     private BindingManagerBase errorManager; 
     private bool initializing; 
     private EventHandler currentChanged; 
     private EventHandler propChangedEvent; 
     private Dictionary<Control, Color> originalColor = new Dictionary<Control, Color>(); 
     private Color errorBackgroundColor; 

     public ContainerControl ContainerControl 
     { 
      [UIPermission(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)] 
      [UIPermission(SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)] 
      get 
      { 
       return parentControl; 
      } 
      set 
      { 
       if (parentControl != value) 
       { 
        if (parentControl != null) 
         parentControl.BindingContextChanged -= propChangedEvent; 

        parentControl = value; 

        if (parentControl != null) 
         parentControl.BindingContextChanged += propChangedEvent; 

        Set_ErrorManager(this.DataSource, this.DataMember, true); 
       } 
      } 
     } 

     public string DataMember 
     { 
      get { return dataMember; } 
      set 
      { 
       if (value == null) value = ""; 
       Set_ErrorManager(this.DataSource, value, false); 
      } 
     } 

     public object DataSource 
     { 
      get { return dataSource; } 
      set 
      { 
       if (parentControl != null && value != null && String.IsNullOrEmpty(this.dataMember)) 
       { 
        // Let's check if the datamember exists in the new data source 
        try 
        { 
         errorManager = parentControl.BindingContext[value, this.dataMember]; 
        } 
        catch (ArgumentException) 
        { 
         // The data member doesn't exist in the data source, so set it to null 
         this.dataMember = ""; 
        } 
       } 
       Set_ErrorManager(value, this.DataMember, false); 
      } 
     } 

     public override ISite Site 
     { 
      set 
      { 
       base.Site = value; 
       if (value == null) 
        return; 

       IDesignerHost host = value.GetService(typeof(IDesignerHost)) as IDesignerHost; 
       if (host != null) 
       { 
        IComponent baseComp = host.RootComponent; 

        if (baseComp is ContainerControl) 
        { 
         this.ContainerControl = (ContainerControl)baseComp; 
        } 
       } 
      } 
     } 
     private ToolTip toolTip; 

     public ToolTip ToolTip 
     { 
      get { return toolTip; } 
      set { toolTip = value; } 
     } 

     public Color ErrorBackgroundColor 
     { 
      get { return errorBackgroundColor; } 
      set { errorBackgroundColor = value; } 
     } 

     private void Set_ErrorManager(object newDataSource, string newDataMember, bool force) 
     { 
      if (inSetErrorManager) 
       return; 
      inSetErrorManager = true; 
      try 
      { 
       bool dataSourceChanged = this.DataSource != newDataSource; 
       bool dataMemberChanged = this.DataMember != newDataMember; 

       //if nothing changed, then do not do any work 
       // 
       if (!dataSourceChanged && !dataMemberChanged && !force) 
       { 
        return; 
       } 

       // set the dataSource and the dataMember 
       // 
       this.dataSource = newDataSource; 
       this.dataMember = newDataMember; 

       if (!initializing) 
       { 
        UnwireEvents(errorManager); 

        // get the new errorManager 
        // 
        if (parentControl != null && this.dataSource != null && parentControl.BindingContext != null) 
        { 
         errorManager = parentControl.BindingContext[this.dataSource, this.dataMember]; 
        } 
        else 
        { 
         errorManager = null; 
        } 

        // wire the events 
        // 
        WireEvents(errorManager); 

        // see if there are errors at the current 
        // item in the list, w/o waiting for the position to change 
        if (errorManager != null) 
         UpdateBinding(); 
       } 
      } 
      finally 
      { 
       inSetErrorManager = false; 
      } 
     } 

     public void UpdateBinding() 
     { 
      ErrorManager_CurrentChanged(errorManager, EventArgs.Empty); 
     } 

     private void UnwireEvents(BindingManagerBase listManager) 
     { 
      if (listManager != null) 
      { 
       listManager.CurrentChanged -= currentChanged; 
       listManager.BindingComplete -= new BindingCompleteEventHandler(this.ErrorManager_BindingComplete); 

       CurrencyManager currManager = listManager as CurrencyManager; 

       if (currManager != null) 
       { 
        currManager.ItemChanged -= new ItemChangedEventHandler(this.ErrorManager_ItemChanged); 
        currManager.Bindings.CollectionChanged -= new CollectionChangeEventHandler(this.ErrorManager_BindingsChanged); 
       } 
      } 

     } 

     private void WireEvents(BindingManagerBase listManager) 
     { 
      if (listManager != null) 
      { 
       listManager.CurrentChanged += currentChanged; 
       listManager.BindingComplete += new BindingCompleteEventHandler(this.ErrorManager_BindingComplete); 

       CurrencyManager currManager = listManager as CurrencyManager; 

       if (currManager != null) 
       { 
        currManager.ItemChanged += new ItemChangedEventHandler(this.ErrorManager_ItemChanged); 
        currManager.Bindings.CollectionChanged += new CollectionChangeEventHandler(this.ErrorManager_BindingsChanged); 
       } 
      } 
     } 


     private void ErrorManager_BindingsChanged(object sender, CollectionChangeEventArgs e) 
     { 
      ErrorManager_CurrentChanged(errorManager, e); 
     } 

     private void ParentControl_BindingContextChanged(object sender, EventArgs e) 
     { 
      Set_ErrorManager(this.DataSource, this.DataMember, true); 
     } 

     private void ErrorManager_ItemChanged(object sender, ItemChangedEventArgs e) 
     { 
      BindingsCollection errBindings = errorManager.Bindings; 
      int bindingsCount = errBindings.Count; 

      // If the list became empty then reset the errors 
      if (e.Index == -1 && errorManager.Count == 0) 
      { 
       for (int j = 0; j < bindingsCount; j++) 
       { 
        if ((errBindings[j].Control != null)) 
        { 
         // ...ignore everything but bindings to Controls 
         SetError(errBindings[j].Control, ""); 
        } 
       } 
      } 
      else 
      { 
       ErrorManager_CurrentChanged(sender, e); 
      } 
     } 

     private void SetError(Control control, string p) 
     { 
      if (String.IsNullOrEmpty(p)) 
      { 
       if (originalColor.ContainsKey(control)) 
        control.BackColor = originalColor[control]; 
       toolTip.SetToolTip(control, null); 
      } 
      else 
      { 
       control.BackColor = ErrorBackgroundColor; 
       toolTip.SetToolTip(control, p); 
      } 
     } 

     private void ErrorManager_BindingComplete(object sender, BindingCompleteEventArgs e) 
     { 
      Binding binding = e.Binding; 

      if (binding != null && binding.Control != null) 
      { 
       SetError(binding.Control, (e.ErrorText == null ? String.Empty : e.ErrorText)); 
      } 
     } 

     private void ErrorManager_CurrentChanged(object sender, EventArgs e) 
     { 
      if (errorManager.Count == 0) 
      { 
       return; 
      } 

      object value = errorManager.Current; 
      if (!(value is IDataErrorInfo)) 
      { 
       return; 
      } 

      BindingsCollection errBindings = errorManager.Bindings; 
      int bindingsCount = errBindings.Count; 

      // We can only show one error per control, so we will build up a string... 
      // 
      Hashtable controlError = new Hashtable(bindingsCount); 

      for (int j = 0; j < bindingsCount; j++) 
      { 

       // Ignore everything but bindings to Controls 
       if (errBindings[j].Control == null) 
       { 
        continue; 
       } 

       string error = ((IDataErrorInfo)value)[errBindings[j].BindingMemberInfo.BindingField]; 

       if (error == null) 
       { 
        error = ""; 
       } 

       string outputError = ""; 

       if (controlError.Contains(errBindings[j].Control)) 
        outputError = (string)controlError[errBindings[j].Control]; 

       // VSWhidbey 106890: Utilize the error string without including the field name. 
       if (String.IsNullOrEmpty(outputError)) 
       { 
        outputError = error; 
       } 
       else 
       { 
        outputError = string.Concat(outputError, "\r\n", error); 
       } 

       controlError[errBindings[j].Control] = outputError; 
      } 

      IEnumerator enumerator = controlError.GetEnumerator(); 
      while (enumerator.MoveNext()) 
      { 
       DictionaryEntry entry = (DictionaryEntry)enumerator.Current; 
       SetError((Control)entry.Key, (string)entry.Value); 
      } 
     } 


     public void BeginInit() 
     { 
      initializing = true; 
     } 

     public void EndInit() 
     { 
      initializing = false; 
      Set_ErrorManager(this.DataSource, this.DataMember, true); 
     } 
    } 
}