0

在具有从基类继承的多个窗口的应用程序中 - 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 的连接。

我该如何解决这个问题?或者,我可以使用哪些其他技术来实现这一目标?

4

2 回答 2

2

除了从基本窗口继承外,您还可以将其作为“子”窗口的容器,例如通过将它们制作成 Pages 并将它们放入基本窗口内的 Frame 中,或者通过将它们制作成 UserControls 并使用 DataTemplates 在它们之间切换不同的窗户。

您还可以使用 ContentPresenter 使您的 BaseWindow 成为 UserControl,而不是从它继承,您可以将其用作窗口的第一个内容元素,并将它们需要显示的任何其他内容放入其中。

于 2013-05-01T08:05:34.070 回答
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;
}
于 2013-05-02T07:09:47.617 回答