2014-11-05 41 views
1

我有一個窗口的基類,其中包含許多這類窗口常見的事件處理程序(它們激發常用的驗證方法)。從xaml的父類附加事件處理程序

下面是一個例子事件處理程序:

protected virtual void ValidateTextBoxTextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) 
{ 
    ValidateProperty((FrameworkElement)sender, TextBox.TextProperty); 
} 

並有大約20的這些,覆蓋公共控件。

每個窗口實例都是從基類的子類構建的。在子類的.xaml我做的:

<TextBox 
    TextChanged="ValidateTextBoxTextChanged"/> 

但是,當我瀏覽到這個窗口,我得到以下錯誤:

Failed to assign to property 'System.Windows.Controls.TextBox.TextChanged'.

所以它沒有找到事件處理程序。有沒有一種優雅的方式可以分配事件處理程序,而不需要在每個子類中重複它們(約30個孩子和計數)?

+0

請顯示一個更完整的代碼示例。至少,它需要顯示完整的上下文,即該方法在哪個類中,該類如何與您的XAML相關聯,當然也包括XAML本身中的上下文。請參閱http://stackoverflow.com/help/mcve – 2014-11-05 17:33:37

回答

3

這很有趣 - 它似乎是事件機制的侷限性,只檢查部分代碼隱藏類,而不是它的基類。 (此問題也已被提出herehere。)我想不出一個理想的解決方法。

當然,你可以通過把虛擬覆蓋在每個子類中修復錯誤:

protected override void ValidateTextBoxTextChanged(object sender, TextChangedEventArgs e) 
{ 
    base.ValidateTextBoxTextChanged(sender, e); 
} 

現在,理所當然地認爲,似乎是一個麻煩。另一種方法是使用觸發器/動作組合來調用基類方法:

<TextBox> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="TextChanged"> 
      <ei:CallMethodAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=local:BaseWindow}}" MethodName="ValidateTextBoxTextChanged" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
</TextBox> 

爲此,您需要使該方法公開。您可以使用上述變體來簡化語法並減少綁定數量:使用附加屬性應用觸發器,並將驗證方法置於靜態資源中,並帶有可選的覆蓋。


另一種可能的方法是繼承TextBox本身,並把您的驗證邏輯存在。您可以公開一個依賴項屬性,以允許擴展TextBox的實例覆蓋默認驗證邏輯。

0

我得到了這個代碼工作。我有一個具有幾descendats

<Page x:Class="mycls"><Button x:Name="mybrn"/></Page> 

繼承其基本XAML頁面和一些觀點:

<local:mycls x:Class="mychild"></local:mycls> 

如果我分配在XAML監聽器,它並沒有在子視圖中工作。但在代碼隱藏它的工作原理:

public mycls() 
{ 
    InitializeComponent() 
    (this.FindName("mybtn") as Button).Click += mybtn_click; 
} 

在此子視圖「inhherit」也處理程序。

相關問題