65.9K
CodeProject 正在变化。 阅读更多。
Home

创建可重用的 WPF UI:第一部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (10投票s)

2013 年 4 月 29 日

CPOL

4分钟阅读

viewsIcon

36951

可重用方法..

引言

当我们在 WPF 中工作时,我们可以创建可重用的 UI 控件。在本文中,我们将看到什么是可重用 UI,以及我们如何使用或创建它们。同时也会介绍我们从中获得的一些优势。

什么是可重用UI?

简而言之,我们可以说,每当我们重用视图或页面中的某个 UI 控件时,我们就说我们正在使用可重用 UI。这意味着重用资源、模板、自定义元素、自定义控件。

创建可重用 UI 的方法。  

基本上有五种创建或使用可重用 UI 的方法。 它们是

  • 资源重用 
  • 模板重用 
  • XAML 重用 
  • 自定义元素 
  • 自定义控件

在本文中,我们将看到前两种方法。 我们将在下一篇文章中看到其余项目。 
资源重用

使 UI 可重用的简单方法是使用资源系统,尽管它的价值有限。 仅仅是因为它不适用于框架元素。 其中的想法是使用声明为静态资源的任何 UI 资源。 让我们看看我们如何做到这一点..

<Window.Resources>
    <TextBlock x:Key="SharedTB" Text="Hello"/>
    <Button x:Key="SharedBT" Content="Hi"/>
</Window.Resources>

<StackPanel VerticalAlignment="Center">
    <StaticResource ResourceKey="SharedTB"/>
    <StaticResource ResourceKey="SharedBT"/>
    <StaticResource ResourceKey="SharedTB"/>
    <StaticResource ResourceKey="SharedBT"/>
</StackPanel>

在上面的示例中,我们可以看到我们在 Windows 资源中声明了一个 TextBlock 和 Button。 我们在 StackPanel 中多次使用了它们。 现在,每当我们运行此代码时,我们都会看到一个 XamlParseException 错误。 现在为什么会这样? 如果我们检查资源的声明,我们可以看到这两个 UI 控件仅定义了内容或文本属性。 它们都是框架元素。 默认情况下,资源系统使每个资源引用到相同的底层对象。 这就是为什么当我们尝试多次使用资源时会出错的原因。

这种方式适用于那些可以共享对象实例本身的重用场景。 所以这种方式适用于动画、画笔、绘图等可冻结元素。 但对于框架元素来说,这不是正确的方法。 尽管有一种替代方法可以为框架元素做同样的事情。 为此,我们所要做的就是在我们的资源声明中设置以下属性。

x:Shared = "False"

所以上面的代码应该像这样

<Window.Resources>
    <TextBlock x:Key="SharedTB" x:Shared="False"  Text="Hello"/>
    <Button x:Key="SharedBT" x:Shared="False"  Content="Hi" Click="Button_Click"/>
</Window.Resources>

<StackPanel VerticalAlignment="Center">
    <StaticResource ResourceKey="SharedTB"/>
    <StaticResource ResourceKey="SharedBT"/>
    <StaticResource ResourceKey="SharedTB"/>
    <StaticResource ResourceKey="SharedBT"/>
</StackPanel>  

基本上它告诉的是,每当请求此资源的引用时,资源管理系统将不会共享相同的实例,而是为每个请求创建一个新实例。 这仅适用于已编译的 XAML 场景。 这就是我们看不到“共享”选项的原因。 现在运行此 XAML,我们将看到一切正常。

模板重用

使 UI 可重用的另一种方法是模板重用。 现在基本上有两种类型的模板:控件模板和数据模板。 我们可以将这两个模板用于此目的。 我们使用控件模板来呈现或自定义特定控件,并在我们的 UI 中重用它。 我们使用数据模板以不同的格式呈现数据。 根据具体情况,我们决定使用哪个模板。 还有一件事是我们可以向我们的模板添加行为。 例如,我们可以向 XAML 声明事件处理程序,并且每次实例化模板时,此处理程序都将连接到代码隐藏中的函数。 每次我们使用一个模板时,它都会生成自己的一个新副本。 让我们直接进入一个使用控件模板的示例。

<StackPanel VerticalAlignment="Center">
    <StackPanel.Resources>
        <ControlTemplate x:Key="TBox">
            <TextBox>
                Hello
            </TextBox>                
        </ControlTemplate>
    </StackPanel.Resources>
    
    <Control Template="{StaticResource TBox}" Focusable = "False" />
    <Control Template="{StaticResource TBox}" Focusable = "False" />
    <Control Template="{StaticResource TBox}" Focusable = "False" />
</StackPanel>

在上面的示例中,我们声明了一个控件模板,我们在其中定义了一个文本框。 然后我们将其用作静态资源以用于可重用 UI 的目的。 检查我们已将 Focusable 属性设置为 False。 这是因为如果我们不这样做,每个文本框都会有两个焦点值。 为可重用 UI 的目的使用控件模板真的没有必要。 我们也可以使用数据模板。 这只是你如何定义你的模板来完成这项工作。 在下面的示例中,我们将看到使用数据模板的相同内容。

<StackPanel VerticalAlignment="Center">
    <StackPanel.Resources>
        <DataTemplate x:Key="TBox">
            <TextBox>
                Hello
            </TextBox>
        </DataTemplate>
    </StackPanel.Resources>

    <ContentPresenter ContentTemplate="{StaticResource TBox}"  />
    <ContentPresenter ContentTemplate="{StaticResource TBox}"  />
    <ContentPresenter ContentTemplate="{StaticResource TBox}"  />
</StackPanel>

您可以看到我们已经用数据模板替换了控件模板,并用 Contentpresenter 替换了控件。 那么什么是 Contentpresenter 呢? 在一个非常短的句子中“它有点像 XAML 内容的占位符。它还具有在运行时插入内容的功能。” 这只是一个关于我们如何做事情的小例子。

© . All rights reserved.