2012-08-03 118 views
1

我知道這個問題可能會得到很多「重複問題」的評論,但我還沒有看到一個有效的答案或不是簡單地「避免它成本」。但是在這裏,我創建了一個控件,在一個名爲「ControlA_Project」的項目中稱其爲「ControlA」,並且我打算在一個名爲「ControlB」的控件中覆蓋它的一些虛擬方法,該控件繼承另一個名爲「ControlA」 ControlB_Project「。這個想法是「ControlA」保存和加載方法,我希望從保存和加載到文件,也保存和加載到數據庫(如果稍後需要另一個保存和加載類型,我可以重寫這些方法再次) 。 我的問題是我最初有一個「ControlA」作爲一個用戶控件,當我試圖添加新的控制覆蓋(「ControlB」)到一個窗口我會得到這個錯誤:用戶控件,自定義控件,繼承和覆蓋

組件'ControlB_Project.ControlB '沒有URI標識的資源'/ControlA_Project;component/usercontrols/ControlA.xaml'。

使用谷歌搜索錯誤我得出的結論是你不能從用戶控件繼承(或者爲了爭辯,這不是一個好主意)。所以我然後將控件從用戶控件更改爲自定義控件。然而這然後導致我另一個問題,一個控件的模板沒有鏈接到後面的代碼(即On_Click),就像它在用戶控件中一樣,並且沒有簡單的方法來簡單地重寫行爲(據我所知) 。我知道我可以通過複製和粘貼ControlAs模板並更改幾行來重新模板ControlB,但controlA擁有一個大模板,因此它使多個副本看起來浪費空間。 那麼簡單地說,有沒有一種正確的方法來改變wpf控件的行爲?

+0

遺憾地說,但你這樣做是錯的。 YOu正在將LOGIC與UI混合使用。引用你「這個想法是」ControlA「保存和加載方法,我希望從保存和加載到文件,也保存並加載到數據庫」。你的問題在於一個錯誤的架構,如果用戶界面不能執行邏輯,就不會存在。 WPF不喜歡這種方法。例如Google MVVM或DataBinding。 – 2012-08-03 14:29:26

+0

我與馬裏諾在這一個。如果存儲策略是控制A和控制B的唯一區別,那麼爲什麼不把它放到自己的類中並保持一個控制?在ControlA_Project中,將其賦予文件存儲類,並在B項目中爲其賦予數據庫實現。 – Vegar 2012-08-03 19:41:49

+0

只是一個建議 - 當您讓UI層專注於呈現數據並將數據和邏輯層移出UI並將其轉化爲專用類時,WPF的確會發光。像其他人所說的,我建議查看Model-View-ViewModel(MVVM)模式 – cordialgerm 2012-08-04 00:12:23

回答

2

首先,請記住ControlTemplate可以被用戶很多地改變,所以你需要確保重要的字段被清楚標記。 所以,如果你想要一個OnClick事件。第一個標記您的按鈕爲「重要」

<Button x:Name="PART_MyButton"/> 

它也是一個好主意,以紀念在你的控制類此藏漢

[TemplatePart(Name = "PART_MyButton", Type = typeof(Button))] 
public class MyCustomControl : Control 

現在要附加到該按鈕的Click事件做那,覆蓋OnApplyTemplate方法。

public override void OnApplyTemplate() 
{ 
    mButton = Template.FindName("PART_MyButton", this) as Button; 
    mButton.Click += MyEventHandler; 
} 

根據您的控件如何在沒有控件的情況下工作,您應該優雅地處理未找到的控件或拋出異常。

最後一件事是。如果您覆蓋具有默認樣式的控件,則提供新的默認樣式可能是個好主意。

static MyCustomControl() 
{ 
    DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl))); 
} 

,並把隱式的風格在你generic.xaml

+0

Urgg im這樣一個木偶,我已經在另一個控制中完成了,甚至沒有想到這一點。謝謝dowhilefor。 – 2012-08-03 14:36:56