UserControl的目的是什么?

时间:2015-11-30 15:55:15

标签: wpf xaml user-controls

为什么我们确实需要用户控件?

窗口:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication1="clr-namespace:WpfApplication1">

    <wpfApplication1:SaveCloseUserControl />

</Window>

用户控制:

<UserControl x:Class="WpfApplication1.SaveCloseUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Horizontal">
    <Button Height="30" Content="Save" />
    <Button Height="30"
            Margin="1"
            Content="Cancel" />
</StackPanel>
</UserControl>

代码背后:

public partial class SaveCloseUserControl : UserControl
{
    public SaveCloseUserControl()
    {
        InitializeComponent();
    }
}

如果没有UserControl的以下代码完全相同,我没有看到为什么我应该在UserControl中包装StackPanel(或任何其他控件)的原因。

窗口:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication1="clr-namespace:WpfApplication1">

    <wpfApplication1:SaveCloseStackPanel />

</Window>

没有用户控制的堆栈面板:

<StackPanel x:Class="WpfApplication1.SaveCloseUserControl"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Orientation="Horizontal">
    <Button Height="30" Content="Save" />
    <Button Height="30"
            Margin="1"
            Content="Cancel" />
</StackPanel>

代码背后:

 public partial class SaveCloseUserControl : StackPanel
 {
    public SaveCloseUserControl()
    {
        InitializeComponent();
    }
 }

我到处都在使用UserControls,但现在当我想到它时,除了包装一个项目之外,它们什么都不做。所以我尝试了10个不同的视图,无论它是什么,我能够将UserControl替换为其他项目(Grid,ComboBox,GroupBox等),并且它们的工作方式完全相同。所以要清楚,如果我有一个用户控件,其中第一件事是ComboBox,那么我删除了UserControl并将ComboBox放在其位置。内部的所有内容都保持不变,就像上面的StackPanel示例一样。

为什么我甚至不打扰UserControl,如果没有做任何事情,还要创建和渲染另一个项目?

4 个答案:

答案 0 :(得分:13)

UserControl的目的是将一组控件分组组合成一个可重用的组件。他们无法进行样式化或模板化。

Custom Control的目的是扩展现有控件,或创建全新控件。与UserControl 相反,可以对这些进行样式化和模板化。

我认为你和这两个人搞混了。

所以,您可能想知道,“我应该何时使用UserControl,何时应该使用Custom Control?”,这取决于具体情况。

当您需要创建一个逻辑控件组时,您应该使用UserControl,这些控件以某种方式交互以创建几乎复合控件。当您想要添加功能到现有控件时,您应该使用Custom Control

在您的示例中,您最好的方法是使用UserControl,因为您的StackPanel是一个控件组成一个可重用组件。

您可以找到更多herehere

答案 1 :(得分:2)

UserControl的目的是帮助您构建可以添加到工具箱中的可重用UI组件,就像内置控件一样,从零开始。 前缀&#34;用户&#34;这有点意味着&#34;不是来自WPF团队&#34;。 WPF不发送任何派生自UserControl的类。

UserControls的一个非常重要的方面是你可以使用XAML设计它们(因此它们可以是复合的),并将代码+ XAML打包在一起,可能在一个&#34;库中#34;您可以在没有来源的情况下装运的装配。

现在,你的例子非常贫乏(没有冒犯:-),他们没有做任何有趣的事情,我很想让它们真正重复使用。大多数情况下,在意识到您已经多次重复相同的XAML模式(可能有一些变化)后,您将根据使用情况(或体验)构建UserControl。

例如在这个开源项目(Github for Visual Studio)中:https://github.com/github/VisualStudio/tree/master/src/GitHub.UI/Controls,你会看到他们编写了一些自定义控件,比如EmojiImage(源自Image,不需要XAML) ),和一个UserControl:Horizo​​ntalShadowDivider。为什么?因为Horizo​​ntalShadowDivider具有与之关联的XAML,并且(可能)在多个地方使用。

答案 2 :(得分:2)

我已从某本书的某处读过(抱歉忘记了书名...),UserControl是一个“块箱”容器。

由于我对该术语的理解并使用您的示例作为基础,您可以看到StackPanel派生的约束到StackPanel布局两个按钮的能力 - 水平或垂直。将来,如果这个布局发生了变化(可能是一个新要求?),你需要创建一个新的面板派生类(或者重写现有的类)并使用它,比如说一个DockPanel。这很糟糕。

在导出的UserControl上,您只需将StackPanel更改为适合新要求的其他面板类型。

这使得UserControl成为一个阻止框,恕我直言。

答案 3 :(得分:1)

根据您的示例,如果您仅使用一次用户控件,那么它就没那么有用了。 但在这种情况下,如果一些设计部分被使用了很多次,并且每次你编写一个xaml代码或任何其他逻辑来创建相同的UI,那么用户控件就会出现在游戏中。