首页 文章

如何在WPF中仅检查Visual Studio 2010设计器(以便Blend的设计器不是目标)?

提问于
浏览
2

我加载了事件(比如通过 VisualStateManager.GoToState(this, "AfterLoaded", true); 这样的调用转换到不同的视觉状态) .

我解决这些设计器崩溃的典型方法是在控件的构造函数中使用DesignerProperties.GetIsInDesignMode(this) approach

public MyControl()
{
    // prevent designer crashes
    if (DesignerProperties.GetIsInDesignMode(this))
        return;

    Loaded += MyControlLoaded;
    Unloaded += MyControlUnloaded;
    IsVisibleChanged += MyControlIsVisibleChanged;    
}

此方法针对Visual Studio 2010和Expression Blend 4,使我能够再次显示我的设计图面 . 但是,它还删除了设计人员可能为我提供的任何设计时预览(例如上面提到的加载事件的VSM状态更改) . 特别是Blend能够在其设计器中为我提供预览(如果我切换到不同的Blend选项卡,然后切换回原始选项卡,我会看到加载的动画运行) . 此外,有些控件我尚未应用上述方法,因此Visual Studio 2010设计师不会 . 因此,我想要检查 only Visual Studio 2010 's designer so that I can let Blend' s设计师是否通过并提供其预览功能 .

这种能力的好处是我可以节省时间,因为不需要经常构建和运行应用程序(看看加载动画之类的东西),因为Blend的设计师可以给我预览 .

3 回答

  • 1

    我找到了有用的东西 . 这个想法是使用 DesignerProperties.GetIsInDesignMode(...) 方法结合 checking for the process name that is running the code .

    对于我的VisualStudio 2010,我看到进程名称为“devenv”:

    Visual Studio Process name

    然后我找到this post,这解释了 System.Diagnostics.Process 是我们需要获得的过程信息 . 知道了,我创建了这个帮助方法:

    private bool IsVisualStudio2010DesignerRunning()
    {
        using (var process = System.Diagnostics.Process.GetCurrentProcess())
        {
            const string visualStudio2010ProcessName = "devenv";
    
            if (process.ProcessName.ToLowerInvariant().Contains(visualStudio2010ProcessName)
                && DesignerProperties.GetIsInDesignMode(this))
            {
                return true;
            }
            else
                return false;
        }
    }
    

    为了说明这是有效的,下面是它的应用示例

    它在我写的一个名为SunkenBorder的自定义控件中 . 此控件具有在第一次机会时转换为某个VisualState的行为,因此该状态是用户看到的初始状态 . 此代码在 OnApplyTemplate() 覆盖中执行 . Expression Blend 4能够在运行时处理和显示它 . 另一方面,Visual Studio 2010的设计器完全崩溃,因为它无法执行由 VisualStateManager.GoToState(...) 调用启动的 Storyboard .

    为了更好地说明这是有效的,我在针对VS 2010设计器的 OnApplyTemplate() 代码中将控件的background属性设置为蓝色(参见屏幕截图) .

    /// Non-static constructor
        public SunkenBorder()
        {
            // Avoid Visual Studio 2010 designer errors
            if (IsVisualStudio2010DesignerRunning())
                return;
    
            // Expression Blend 4's designer displays previews of animations 
            //  that these event handlers initiate!
            Initialized += new EventHandler(SunkenBorder_Initialized);
            Loaded += new RoutedEventHandler(SunkenBorder_Loaded);
            Unloaded += new RoutedEventHandler(SunkenBorder_Unloaded);
    
            IsVisibleChanged += new DependencyPropertyChangedEventHandler(SunkenBorder_IsVisibleChanged);
        }
    
        // ...
    
        /// Used to set the initial VSM state (its the first opportunity).
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
    
    
            if (IsVisualStudio2010DesignerRunning())
            {
                // set a property just to illustrate that this targets only Visual Studio 2010:
                this.Background = Brushes.Blue;
                // return before doing VisualState change so Visual Studio's designer won't crash
                return;
            }
            // Blend 4 executes this at design-time just fine
            VisualStateManager.GoToState(this, "InitialState", false);
    
            // ...
        }
    

    以下是Expression Blend 4预览的外观(注意SunkenBorder控件的背景不是蓝色)......

    Blend 4 designer preview

    ......这就是Visual Studio设计师向我展示的内容 . 现在它的设计师没有崩溃,而且SunkenBorder控件的背景都是蓝色的......

    Visual Studio 2010 designer preview

    ...最后,这是运行时的结果(再次,SunkenBorder控件的背景不是蓝色):

    enter image description here

  • 0

    你可能会更好地制作一个design time view model . 这将消除必须在控件的构造函数中检查任何类型的设计器 .

  • 0

    (注意:现在不能测试/验证这个,稍后会这样做)

    看起来 Silverlight 人员在进行"In Designer"检查时离开了农场,所以现在有两个属性:

    • IsInDesignMode ,这似乎与VS2010一致

    • IsInDesignTool ,这似乎对Blend来说是半持续的

    还发现了这个:

    http://www.arrangeactassert.com/how-to-use-the-designerproperties-isindesigntool-property-to-populate-controls-with-design-time-data-in-silverlight-using-expression-blend/

相关问题