从工具箱中的程序集隐藏所有 WPF 用户控件

Hide all WPF UserControls from Assembly in Toolbox

我想在 Visual Studio 工具箱 中的项目中的多个程序集中隐藏所有已编写的 WPF 用户控件。我知道我可以用 [DesignTimeVisible(false)] 属性标记 UserControls 来隐藏每个单独的控件。

是否有另一种解决方案可以将它们全部隐藏在程序集上的一个属性中?我不想标记每个新控件。遗憾的是,该属性不是从其父级继承的,因此我什至无法使用 DesignTimeVisible(false) 创建基本控件。

有什么想法吗?

作为首选,此类控件可以 internal 如果它们应该在容器项目中可见使用。您可以根据需要将它们设为 public。同样是内部的,它们也可以在 friend assemblies 中使用。

反正降低DesignTimeVisible转on/off的难度就是你要找的,可以考虑这些方案:

选项 1

作为一个选项,您可以降低 on/off DesignTimeVisible 属性的难度。您可以用 DesignTimeVisible 装饰所有 class 一次,但从一个中心点控制它的值。

为此,创建一个 class 来保存设置:

public class MyGlobalSettings
{
    public const bool DesignTimeVisible = false;
}

然后这样装饰控件:

[DesignTimeVisible(MyGlobalSettings.DesignTimeVisible)]
public partial class UserControl1 : UserControl

然后转on/off显示工具箱中的控件,设置DesignTimeVisible即可。这样,它只是一个单点设置。

选项 2

另一个选项是您可以使用 T4 模板为您的控件生成部分 classes。在文件中,您可以有一个变量,它将用作 DesignTimeVisible 属性的值。然后在 T4 模板中,用具有指定值的 DesignTimeVisible 装饰所有部分 classes。您可以简单地更改单个点的值。

Class 名称可以使用代码自动生成,但在本例中我使用静态 class 名称:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#  var designTimeVisibleValue = "false"; #>
using System.Windows.Controls;
using System.ComponentModel;
namespace WpfCustomControlLibrary1
{
    [DesignTimeVisible(<#=designTimeVisibleValue#>)]
    public partial class UserControl1 : UserControl{}

    [DesignTimeVisible(<#=designTimeVisibleValue#>)]
    public partial class UserControl2 : UserControl{}
}

备注

另外如评论中所述,您可以使用 Fody、PostSharp、dIHook 等工具在构建时修改程序集。仅仅为了这样的需求而使用这些库是太多了。这样的工具可以有很多好处,但是仅仅为了这样的需求而使用它们太过分了,不是一个好主意。

也许我迟到了,但是如果:

  1. 您的控件程序集未在 GAC 中注册
  2. 您的控件程序集项目不在您正在使用的解决方案中

那么你可以使用WPF Designer Extensibility。实际上,您可以使用属性扩展 visual studio WPF 设计器。

我们需要的属性是ToolboxBrowsableAttribute。这个框架更重要的特点是它允许在一个单独的程序集(称为设计程序集)中为我们的控件定义属性。

所以让我们假设这些是我们的自定义控件:

namespace CustomControls
{
    public class CustomTextBox : TextBox
    {
    }

    public class CustomButton : Button
    {
    }

    public class CustomComboBox : ComboBox
    {
    }
}

自定义控件位于名为 CustomControls.dll 的程序集中;为了向每个控件添加我们需要的属性,应该创建一个名为 CustomControls.Design.dll 的新程序集。这个新程序集必须参考:

  • PresentationCore
  • PresentationFramework
  • System.Xaml
  • WindowsBase
  • Microsoft.Windows.Design.Extensibility
  • Microsoft.Windows.Design.Interaction

在 AssemblyInfo 中添加这行代码:

[assembly: ProvideMetadata(typeof(CustomControls.Design.Metadata))]

该属性指出了class将为设计者提供的属性。 那么我们来看看Metadataclass:

的代码
namespace CustomControls.Design
{
    public class Metadata : IProvideAttributeTable
    {
        AttributeTable IProvideAttributeTable.AttributeTable
        {
            get
            {
                AttributeTableBuilder builder = new AttributeTableBuilder();
                Assembly assembly = Assembly.GetAssembly(typeof(CustomControls.CustomButton));

                foreach (Type objectType in assembly.GetTypes())
                {
                    if (objectType.IsPublic && typeof(FrameworkElement).IsAssignableFrom(objectType))
                    {
                        builder.AddCustomAttributes(objectType,
                            ToolboxBrowsableAttribute.No);
                    }
                }

                return builder.CreateTable();
            }
        }
    }
}

通过这种方式,我将 ToolboxBrowsable 属性添加到扩展 FrameworkElement class 的 CustomControl 程序集的每个 public 对象,而无需需要一个一个装饰每个控件。

CustomControls.Design.dll 必须在 CustomControls.dll.

的同一文件夹中

您可以找到有用的信息 here(即使该代码考虑的参数略有不同)。

注意:如果条件一和条件二不满足,则此方法无效,可能Reza Aghaei的解决方案更合适。

希望能帮到你