2

多くの場合、VisualStudio2010またはExpressionBlend4のデザイナーは、たとえば、WPF UserControlにコントロールが含まれている場合、コントロールのロードされたイベントに基づいてコードで何かを実行するとクラッシュすることがわかりました(別のビジュアル状態への遷移など)のような呼び出しを介してVisualStateManager.GoToState(this, "AfterLoaded", true);

これらのデザイナーのクラッシュを解決するための私の典型的なアプローチは、コントロールのコンストラクターでアプローチを使用することですDesignerProperties.GetIsInDesignMode(this)

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

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

このアプローチは、VisualStudio2010とExpressionBlend4の両方を対象としており、デザインサーフェスを再び表示できるようにします。ただし、設計者が提供する可能性のある設計時のプレビューも削除されます(ロードされたイベントでの前述のVSM状態の変更など)。特に、Blendは、デザイナーでそのプレビューを提供できます(別の[Blend]タブに切り替えてから元のタブに戻すと、読み込まれたアニメーションが実行されます)。さらに、上記のアプローチをまだ適用していない一部のコントロールでは、Visual Studio 2010のデザイナーはクラッシュしますが、Blend4のデザイナーはクラッシュしません。したがって、私がやりたいのは、 Visual Studio 2010のデザイナーのみをチェックして、Blendのデザイナーを通過させてプレビュー機能を提供できるようにすることです。

この機能の利点は、Blendのデザイナーがプレビューを提供できるため、アプリケーションを頻繁にビルドして実行する必要がないため(ロードされたアニメーションなどを表示するため)、時間を節約できることです。

4

3 に答える 3

1

うまくいくものを見つけました。アイデアは、コードを実行しているプロセス名のチェックとDesignerProperties.GetIsInDesignMode(...)組み合わせたアプローチを使用することです。

VisualStudio 2010の場合、プロセス名は「devenv」であることがわかります。

VisualStudioプロセス名

次に、プロセス情報を取得するために必要なものであることを説明するこの投稿を見つけました。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のデザイナは、Storyboardへの呼び出しによって開始されたを実行できないため、完全にクラッシュしVisualStateManager.GoToState(...)ます。

これが機能していることをわかりやすく説明するためにOnApplyTemplate()、VS 2010デザイナーを対象とするコードでコントロールの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);

        // ...
    }

これがExpressionBlend4のプレビューの外観です(SunkenBorderコントロールの背景が青ではないことに注意してください)...

Blend4デザイナープレビュー

...そしてこれがVisualStudioのデザイナーが見せてくれたものです。これで、デザイナーがクラッシュすることはなく、SunkenBorderコントロールの背景はすべて青色になります...

VisualStudio2010デザイナープレビュー

...そして最後に、実行時の結果を次に示します(ここでも、SunkenBorderコントロールの背景は青ではありません)。

ここに画像の説明を入力してください

于 2013-02-08T18:13:15.430 に答える
0

おそらく、デザインタイムビューモデルを作成したほうがよいでしょう。これにより、コントロールのコンストラクターで任意のタイプのデザイナーをチェックする必要がなくなります。

于 2013-01-30T17:56:55.317 に答える
0

(注:現在、これをテスト/検証する立場にはありません。後で行います)

Silverlight「InDesigner」チェックを行ったときに人々が農場を離れたように見えるので、2つのプロパティがあります。

  • 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/

于 2013-01-30T18:45:45.367 に答える