在具有从基类继承的多个窗口的应用程序 - BaseWindow
中,我想在每个窗口上都有一个状态栏。我假设这必须用代码完成,因为一个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);
}
}
引发以下错误:在附加到新的父Visual之前,必须断开指定子项与当前父Visual的连接。
我该如何解决这个问题?或者,我可以用什么其他技术来实现这个目标?
答案 0 :(得分:2)
您可以将其作为“子”窗口的容器,而不是从基本窗口继承,例如通过制作Pages并将它们放入基本窗口内的Frame中,或者将它们设置为UserControls并使用DataTemplates以便在不同的窗口之间切换。
你也可以使用ContentPresenter使你的BaseWindow成为UserControl,而不是从它继承,你可以将它作为你窗口的第一个内容元素,并把它们需要显示的任何内容放在里面。
答案 1 :(得分: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;
}