(粗译) Prism and WPF - 定制 Tab region adapter - 01部分

原作者:Raffaeu

有一件事让我很讨厌,当我开始使用Prism的时候,Prism的开发者没有提供一个好用的 tab region adapter。 好吧,items adapter 提供了完好的标签控制,但如果你开始使用,就会觉得它很糟糕。

我非常肯定,只要你想要发布你的第一个“Visual Studio风格的”Prism应用程序,你的主管会要求一个类似下面的选项卡标签:

image

这是在VS2010上的选项卡标签,正如你可以看到它可以让你:1)关闭当前活动标签,2)标识标签,有一个红色的变化点,3)使用不同的颜色,以便识别活动标签和不同类型的文件。

另一个很酷的标签系统VS 2010,就是一个把Design和XAML分开的标签系统,看这里:

image

我只是喜欢这种非方形标签的风格,它来自我对Chrome浏览器的记忆。

 

Prism region adapter 是如何工作的?

首先,使用Prism默认方式,我们如何在 tab region adapter 中创建一个新的选项卡标签。 你平时做的是将view添加到一个region这样...下面的代码演示了如何定义一个tab region adapter,然后如何添加新的tab。 非常简单。

首先,我们初始化 Shell 项目中的 bootstrapper。

The Shell bootstrapper

protected override System.Windows.DependencyObject CreateShell()
{
    var shell = Container.Resolve<MainWindow>();
    shell.Show();
    return shell;
}
 
protected override IModuleCatalog GetModuleCatalog()
{
    var catalog = new ModuleCatalog()
        .AddModule(typeof(TabModule));
    return catalog;
}

 

然后,准备 Shell XAML Window 中添加我们需要的 regions。

Shell XAML Window

<ItemsControl Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
              cal:RegionManager.RegionName="HeaderRegion" Name="HeaderRegion">
    
</ItemsControl>
<TabControl Grid.Row="1" Grid.Column="1"
            cal:RegionManager.RegionName="TabRegion" Name="TabRegion">
    
</TabControl>

然后,在该 module 中,分配到每个 view 在 shell 的特定 region 。

Module initialization

public sealed class TabModule : IModule
{
    private IRegionManager regionManager = null;
 
    public TabModule(IRegionManager regionManager)
    {
        this.regionManager = regionManager;
    }
 
    public void Initialize()
    {
        regionManager
            .AddToRegion("TabRegion", new FirstView())
            .AddToRegion("TabRegion", new SecondView());
    }
}


你会得到这个丑陋的结果...

image

因为我们没有指定任何样式,你可以看到选项卡不知道如何显示选项卡的标签。

现在,为了解决这个问题有两个简单的解决方案。 第一个是创建一个自定义 region adapter 和重写 region adapter 添加 region 的方法,并为 region adapter 提供所需信息。 这很不错,尤其当您正在使用第三方控件的时候。 第二种方法是有钱人的方法,可以使用第三方控件,但我不使用,原因很简单,作为一个博客,我没有钱... [:)](译者:这句不太会翻译)

一切始于依赖项属性。

XAML很酷,特别是因为它可以让你按照你想要的扩展它,那么为什么我们不开始考虑利用其强大的引擎来实现前面疯狂奇怪的解决方案?? 因此,让我们构建一个简单的 .dll 项目,来实现我们 TabItem 风格的“model”。 这种模式实现我们想要的特性:1)有一个标题,2)可查看或不能被关闭,3)view发生改变,必须保存更改。

Model for a tab item

public sealed class TabModel : DependencyObject
{
    public string Title
    {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
    }
 
    // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.Register("Title", typeof(string), typeof(TabModel));
 
    public bool CanClose
    {
        get { return (bool)GetValue(CanCloseProperty); }
        set { SetValue(CanCloseProperty, value); }
    }
 
    // Using a DependencyProperty as the backing store for CanClose.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CanCloseProperty =
        DependencyProperty.Register("CanClose", typeof(bool), typeof(TabModel));
 
    public bool IsModified
    {
        get { return (bool)GetValue(IsModifiedProperty); }
        set { SetValue(IsModifiedProperty, value); }
    }
 
    // Using a DependencyProperty as the backing store for IsModified.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsModifiedProperty =
        DependencyProperty.Register("IsModified", typeof(bool), typeof(TabModel));
 
}

 

现在我们只需要创建一个 ViewModel 描述 View 中的标签控件。 当然,你的 ViewModel 应该包含整个基础项目,但在这个示例中,我们并不真的需要它! 这是代码:

image

现在,这一切安排好了,我们需要两个以上的代码块。 首先是 ViewModel 为每个 View 的实现 TabItem, 下面的代码是FirstView:

Concrete ViewModel for TabItem

public sealed class FirstViewModel : TabViewModel
{
    public FirstViewModel()
    {
        this.TabModel = new TabModel
        {
            Title = "First View.",
            CanClose = true,
            IsModified = false
        };
    }
}

和非常容易的XAML:

FirstView vm binding

         xmlns:vm="clr-namespace:PrismCustomModule.ViewModels"
         mc:Ignorable="d"
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
    <vm:FirstViewModel />
</UserControl.DataContext>

自定义TabItem的使用样式。

第一步是很容易,只要在Shell项目中添加一个资源字典,然后在Shell Window引用。 创建一个自定义样式的标签,并指定容器如何将我们先前创建的标题文字绑定TabItem model:

Dictionary

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type TabItem}" x:Key="HeaderStyle">
        <Setter Property="Header"
                Value="{Binding RelativeSource={RelativeSource Self},
                    Path=Content.DataContext.TabModel.Title}" />
    </Style>
</ResourceDictionary>

到目前为止还很不错,现在我们只是在Shell中自定义TabContainer,这就是最终结果:

代码片段

<TabControl Grid.Row="1" Grid.Column="1"
            cal:RegionManager.RegionName="TabRegion" Name="TabRegion"
            ItemContainerStyle="{StaticResource HeaderStyle}">
    
</TabControl>

image

很不错,因为TabItem model 是一个属性,可以在ViewModel中引发更改,我们可以在用户打开选项卡时更改此属性的“on fly”。 我们也可以用它来激活一个特定的标签,增加了标签式的行为等等。 但是标签头仍然很烂,和其他很多烂东东! 我是说我真的不喜欢它。 所以在这里,我们可以用 Blend 4和 Design4。

转载于:https://www.cnblogs.com/tanCool/archive/2011/02/11/1951547.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF Prism是微软新一代的界面开发框架,它具有丰富的功能和灵活的架构,广泛应用于桌面应用程序和Web应用程序的开发中。朝夕停车场项目是基于WPF Prism框架的一个实战项目,它实现了停车场的智能化管理,包括车辆进入和出场的自动识别,车位的实时监测和调度,以及财务管理和数据分析等功能。 该项目的源码包含了多个模块和组件,采用了MVVM架构和依赖注入技术,使代码组织和维护非常方便。项目中的主要模块包括: 1. Shell模块:该模块是整个应用程序的容器,它提供了主窗口和导航栏等界面组件,以及对其他模块的管理和协调。 2. Home模块:该模块实现了停车场的实时监控和调度功能,包括车位的占用和空闲状态显示,车辆进出场的记录和管理,以及停车位的预定和预约等功能。 3. Financial模块:该模块实现了停车场的财务管理和数据分析功能,包括车位租赁、停车费用计算和缴纳,以及停车场运营数据的统计和分析等功能。 4. Configuration模块:该模块实现了停车场的基础配置和参数管理功能,包括车位数量、收费标准和系统设置等功能。 5. Common模块:该模块包含了一些公共的模型和工具类,用于提供系统级别的服务和支持。 通过这个实战项目的源码学习,可以深入了解WPF Prism框架的应用及其MVVM架构和依赖注入的设计思想,也可以了解如何实现一个完整的智能化停车场管理系统。同时,该项目源码可以作为一个参考,通过在此基础上进行二次开发和定制,实现更加具体化的应用需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值