从工具箱中的程序集隐藏所有WPF UserControl

时间:2016-10-31 12:21:16

标签: c# .net wpf visual-studio user-controls

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

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

任何想法?

2 个答案:

答案 0 :(得分:1)

作为首选,如果这些控件应该在容器项目中可见,则它们可以是internal。您可以根据要求公开它们。也是内部的,它们也可以在friend assemblies中使用。

无论如何,为了减少打开/关闭DesignTimeVisible的难度,您可以考虑以下选项:

选项1

作为选项,您可以降低打开/关闭DesignTimeVisible属性的难度。您只需使用DesignTimeVisible装饰所有类,但可以从中心点控制其值。

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

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

然后以这种方式装饰控件:

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

然后打开/关闭显示工具箱中的控件,就足以设置DesignTimeVisible。这样,它只是一个单点设置。

选项2

另一个选项是您可以使用T4模板为控件生成部分类。在文件中,您可以拥有一个变量,该变量将用作DesignTimeVisible属性的值。然后在T4模板中,使用具有指定值的DesignTimeVisible装饰所有部分类。您只需在一个点上更改值即可。

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

<#@ 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 :(得分:1)

也许我迟到了,但如果:

  1. 您的控件程序集未在GAC中注册
  2. 您的控件程序集的项目不在您正在使用的解决方案中
  3. 然后你可以使用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))]
    

    该属性指出哪个类将为设计者提供属性。 那么让我们看看Metadata类的代码:

    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属性添加到扩展CustomControl类的FrameworkElement程序集的每个公共对象,而无需逐个装饰每个控件。 / p>

    CustomControls.Design.dll必须位于CustomControls.dll

    的同一文件夹中

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

    支付注意:如果条件1和条件2不满足 ,则此方法不起作用,并且可能Reza Aghaei的解决方案更合适。

    我希望它可以提供帮助。