20

所以我正在构建一个应用程序,它将有很多窗口,所有窗口都具有相同的基本布局:

  1. 一个主窗口
  2. 顶部角落的徽标
  3. 标题栏
  4. 底部的状态显示
  5. 窗口特定控件的区域。

目前我必须在每个窗口中重新创建这个结构。理想情况下,我希望将此布局编码在一个地方,也许是为了便于使用而定制的 Window 子类。有没有人有任何关于如何开始的线索,或者以前遇到过类似问题的经验?

4

4 回答 4

35

您可以创建一个以窗口为目标的新 ControlTemplate 来完成此操作,如下所示。

<ControlTemplate x:Key="WindowControlTemplate1" TargetType="{x:Type Window}">
    <Border 
        Background="{TemplateBinding Background}" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}"
        >
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="0.93*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.21*"/>
                <ColumnDefinition Width="0.79*"/>
            </Grid.ColumnDefinitions>

            <ContentPresenter 
                Grid.ColumnSpan="2" 
                Grid.Row="1" 
                Content="{TemplateBinding Content}" 
                ContentTemplate="{TemplateBinding ContentTemplate}"
                />
            <ResizeGrip 
                HorizontalAlignment="Right" 
                x:Name="WindowResizeGrip" 
                VerticalAlignment="Bottom" 
                IsTabStop="False" 
                Visibility="Collapsed" 
                Grid.Column="1" 
                Grid.Row="2"
                />
            <TextBlock Text="My Logo" />
            <TextBlock Grid.Column="1" Text="My Title"/>
            <StatusBar Height="20" Grid.ColumnSpan="2" Grid.Row="2"/>
        </Grid>
    </Border>

    <ControlTemplate.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="ResizeMode" Value="CanResizeWithGrip"/>
                <Condition Property="WindowState" Value="Normal"/>
            </MultiTrigger.Conditions>
            <Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible"/>
        </MultiTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
于 2009-01-08T00:40:50.543 回答
6

如果您有足够的勇气进行重大的架构转变,您可以考虑来自 Microsoft 的 Patterns & Practices 人员的CompositeWPF (以前代号为 Prism)。

您感兴趣的是能够在外壳(即窗口)中定义“区域”,然后使用视图来填充这些区域。它使用 Model-View-Presenter 模式来允许从模型中独立开发“视图”,而不是随着时间的推移可以轻松地重新定位,因为 shell 只定义区域并且不直接与放置在其中的内容耦合。主要是这有助于将外壳与视图和视图相互分离,并使单元测试更容易......等等等等。

尽管您的情况是 CompositeWPF 旨在解决的应用程序类型之一,但它是一个巨大的飞跃,并且一开始会减慢您的速度。

作为 CompositeWPF 的一部分,您将需要采用可能会使新手感到困惑的各种模式,例如 UnityContainer、控制反转、MVP(或模型/视图/视图模型)和依赖注入。

我记得当我第一次开始对示例应用程序感到困惑时,因为其中一些视图是如何创建的并不明显!统一容器将实例化对象并神奇地调用参数化构造函数。

CompositeWPF 是您问题的一种优雅的解决方案,但不是一个简单或直接的解决方案。在我的上一个项目中使用了 CompositeWPF,我打算在下一个适当的应用程序中再次使用它。

于 2009-01-07T16:08:11.687 回答
2

最简单的方法是为窗口特定控件创建 WPF 一个“页面”,并在主窗口中放置一个“框架”。您甚至可以通过这种方式创建一个不错的导航。

于 2009-01-07T20:00:01.500 回答
-6

你究竟为什么要使用“很多窗户”?为什么不只是一个带有选项卡控件的窗口?还是带有用户控件的单个窗口?

无论如何,要回答您的问题,用户控件是您想要获得您所描述的功能的一种方式。

创建一个新的 Window 类,并使其具有“Childrens”属性,该属性允许将对象嵌入到您希望“窗口特定控件”所在的停靠面板中。

启动新窗口时,实例化窗口类型和具有特定控件的用户控件,将用户控件添加到窗口的 Children 属性,然后显示窗口。您甚至可以绑定事件处理程序、DataContexts 以及目前没有的东西。

于 2009-01-07T14:48:29.647 回答