簡體   English   中英

在派生控件中隱藏基礎 class 依賴屬性

[英]Hiding base class dependency property in derived control

我正在為不同的數據類型編寫一組自定義 TextBox 控件。 我不僅希望驗證文本(我這樣做),而且還希望將輸入存儲在適當類型的屬性中。

例如,我有一個繼承自 TextBox 的 UnsignedIntegerBox,應該將輸入存儲在“uint UnsignedInteger”屬性中,默認設置在 xaml 中。 它驗證 OnPreviewTextInput 事件中的輸入。 OnTextChanged 用於從 Text 更新 UnsignedInteger。

問題:有什么方法可以隱藏 TextBox.Text 屬性,使其在 XAML 中不暴露(也不能使用)?

我建議創建可以從 UserControl / Control class 繼承的新 CustomTextbox class,根據需要在其上創建一個 DP 屬性並將其綁定到控件模板/新控件內容中的 TextBox。 這樣您仍然可以使用 TextBox 進行輸入/視覺效果,但從代碼點來看,它隱藏在您的新 CustomTextBox class 后面

當您擴展超類時,子類就是超類。 您永遠不能刪除超類的任何成員。 您可以通過覆蓋虛擬成員或隱藏可訪問成員來更改行為。 也許您應該重新訪問像 C# 這樣的 OO 語言的 inheritance 規則來理解這個概念。

這是您可以做的,其中 3、4、5 是唯一干凈且有用的解決方案:

  1. 當您隱藏Text屬性以將其聲明為private時,由於 XAML 引擎的類型推斷,您將收到 XAML 錯誤。 這樣,Text 屬性可通過 Intellisense 使用,但您無法設置它。 但是在 C# 中選擇了下一個可訪問的成員。 成員查找行為將自動排除新的隱藏私有Text屬性,然后查找public超類成員。
class MyTextBox : TextBox
{
  // Only has an effect in XAML
  new private string Text { get; set; }
}

即使這可行,您也始終可以使用DependencyObject.SetValue方法設置 static DependencyProperty 隱藏也只是隱藏而不是刪除。 您始終可以強制轉換為超類以訪問原始Text屬性。

  1. 您可以覆蓋DependencyProperty元數據以禁止數據綁定
public class MyTextBox : TextBox
{
  static MyTextBox()
  {
    TextBox.TextProperty.OverrideMetadata(
      typeof(MyTextBox), 
      new FrameworkPropertyMetadata(default, FrameworkPropertyMetadataOptions.NotDataBindable));
  }
}

如果您嘗試綁定Text屬性,這將引發異常。
但是您仍然可以通過賦值來設置值。

  1. 在 inheritance 上使用組合物。 您可以根據您的要求設計 class API 並將功能委托給不可訪問的組合類型。
class MyTextBox : TextBox
{
  private TextBox TextBox { get; }

  public int Number
  { 
     get => return this.TextBox.Text;
     set
     {
       if ( IsValid(value))
       {
         this.TextBox.Text = value;
       }
     }
}
  1. 在不聲明不需要的成員的類型層次結構中擴展 class。 在您的情況下,這將是TextBoxBase
// Will not have a Text property
class MyTextBox : TextBoxBase
{
}
  1. 拋出NotSupportedException異常以使使用繼承的成員成為不可能。 立即通知開發人員,例如, Text屬性不可用。 可能不是公共圖書館的最佳解決方案。
public class MyTextBox : TextBox
{
  static MyTextBox()
  {
    TextBox.TextProperty.OverrideMetadata(
      typeof(MyTextBoxl), 
      new FrameworkPropertyMetadata(null, OnCoerceText));
  }

  private static object OnCoerceText(DependencyObject d, object baseValue) 
    => throw new NotSupportedException();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM