2013-05-01 81 views
0

在具有從基類繼承的多個窗口的應用程序中,我想在每個窗口上都有一個狀態欄。我認爲這必須用代碼完成,因爲一個XAML生成的類不能從另一個繼承。在基本窗口類中包裝窗口內容

的XAML看起來是這樣的:

<my:BaseWindow x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:my="clr-namespace:WpfApplication1"> 
    <StackPanel> 
     <TextBlock Text="Content" /> 
    </StackPanel> 
</my:BaseWindow> 

和BaseWindow類:

public class BaseWindow : Window { 
    protected override void OnContentChanged(object oldContent, object newContent) { 
     var sb = new StatusBar(); 
     sb.Items.Add(new TextBlock { 
      Text = "Status bar" 
     }); 

     var dp = new DockPanel(); 
     dp.Children.Add(sb); 
     DockPanel.SetDock(sb, Dock.Bottom); 
     dp.Children.Add((UIElement)newContent); 

     base.OnContentChanged(oldContent, dp); 
    } 
} 

引發以下錯誤:必須斷開當前父指定子視覺附加到新的父可視化之前。

我該如何解決這個問題?或者,我可以使用其他什麼技術來實現此目的?

+0

哪裏/什麼時候引發這個錯誤? – 2013-05-01 07:52:40

+0

在對'base.OnContentChanged'的調用中。 – 2013-05-01 09:04:23

回答

1

設置Content不是調用base.OnContentChanged作品:

Content = dp; 

然而,設置Content直接將調用OnContentChanged,引起無限循環。根據我現在的需要,一個簡單的標誌就足夠了:

private bool firstRun = true; 
protected override void OnContentChanged(object oldContent, object newContent) { 
    if (!firstRun) { return; } 

    ... 

    firstRun = false; 
    Content = dp; 
} 
2

而不是從基本窗口繼承,你可以使它成爲「孩子」窗口的容器,例如,通過製作頁面並將它們放入基本窗口內的Frame中,或者通過使它們成爲UserControls並使用DataTemplates來在不同窗口之間切換。

您也可以使用ContentPresenter將BaseWindow設置爲UserControl,而不是繼承它,您可以將其用作窗口的第一個內容元素,並將其他內容放在裏面。

+0

我需要從BaseWindow繼承,原因有兩個:BaseWindow公開其他應該可用於每個窗口的功能(屬性/方法),因爲BaseWindow本身從另一個提供附加功能的類繼承。 – 2013-05-01 09:13:14

+0

那麼,在WPF和XAML中,通過聚合重用功能比較常見,即將其放入可重用組件並使用更高級別組中的功能,而不是通過繼承。 – hbarck 2013-05-01 09:16:59

+0

這不是我現在可以改變的東西。 – 2013-05-01 09:48:20