5

Visual Studio 2008 内のすべてのフォームとカスタム コントロールで設計時に問題が発生しています。前回のチェックインまで、すべてのコントロールが期待どおりにレンダリングされていました。現在のバージョンと以前の作業バージョンの唯一の主な違いは、コントロールのプロパティのUIText名前が から に変更されContentたことValueです。その他の変更は、新しいフォームと 3 つの新しい列挙型を追加することですが、プログラム内のすべてのフォーム (新しいものを含む) に影響する明らかな変更はありません。

すべてのコントロール (すべてのフォーム) が、コントロールの名前を持つボックスとしてレンダリングされるようになりました (ただし、実行時にすべて正しくレンダリングされます)。

レンダリングの問題

プロジェクトで新しいフォームを作成し、ラベルだけを付けた新しいカスタム コントロールを作成しようとしましたが、まったく同じ問題が発生します。

奇妙な

標準の .Net フォーム コントロールは正常に動作するため、これはカスタム コントロールのみの問題であることに注意してください。

リポジトリから以前のバージョンを復元すると、すべてが再び正しくレンダリングされ始めます。

正しくレンダリングする

この作業バージョンに戻って続行することもできますが、問題が再発した場合の修正方法を知りたいです。Visual Studios 2008 の問題 (ちなみに SP1) に比べて、プログラミングの問題であることを期待してここに投稿しています。

更新 - 問題を追跡しましたが、説明できません

問題を修正しました。まあ、固定というのは実際には適切な言葉ではありません。フォームが再び適切にレンダリングされるまで、すべてのユーザー コントロールを一度に 1 つずつ削除して、問題を特定しました。この問題は私の署名コントロールにありました (これは何年にもわたって存在していましたが、最新のチェックインでのみ、プロジェクトiVirtualDocket.CodeLibraryへの参照をメイン プロジェクトに追加しました。

  iVirtualDocket
    - References iVirtualDocket.UIControls
    - References iVirtualDocket.CodeLibrary
  iVirtualDocket.UIControls
    -References iVirtualDocket.CodeLibrary

署名にはSignatureData、これを行っていたと呼ばれるプロパティがあります。

public byte[] SignatureData
{
    get
    {
        if (_signature == null)
        {
            return null;
        }
        else
        {
            return iVirtualDocket.CodeLibrary.Conversions.ImageToByteArray(
                _signature, ImageFormat.Png);
        }
    }
}

ImageToByteArray は次のようになります。

public static byte[] ImageToByteArray(Image imageToConvert,
        ImageFormat formatOfImage)
{
    byte[] ret;
    using (MemoryStream ms = new MemoryStream())
    {
        imageToConvert.Save(ms, formatOfImage);
        ret = ms.ToArray();
    }

    return ret;
}

上記のメソッドをUIControlsプロジェクトに移動すると、すべて正常に動作します。ただし、メソッドをプロジェクトに戻しCodeLibraryてそこで呼び出すとすぐに、すべてのフォームが UserControls のレンダリングを停止します。

したがって、次のことを行うと問題は解決しますが、その理由を知りたいです。

public byte[] SignatureData
{
    get
    {
        if (_signature == null)
        {
            return null;
        }
        else
        {
            // Need to call this code directly here instead of through 
            // the CodeLibrary conversions, otherwise all user controls stop 
            // rendering in design mode
            byte[] ret;
            using (MemoryStream ms = new MemoryStream())
            {
                _signature.Save(ms, ImageFormat.Png);
                ret = ms.ToArray();
            }

            return ret;
        }
    }
}

(さらに奇妙なのは、このプロパティをまだ使用していないことです。)

4

3 に答える 3

2

同様の非設計時表示の問題が発生したアプリケーションがあります。いくつかの調査を行うことで(どこで見つけたのか正確には覚えていません)、最終的にファイルを作成しました

DesignTimeAttributes.xmta

そのタイプは「設計時属性ファイル」のタイプです。

その中で、定義した各コントロール クラスを宣言し、それを "DesktopCompatible" として修飾するだけでした。このようにして、デザイナーに描画してもよいことを伝え、一部のコントロール (ハンドヘルド スキャナーの署名コントロールでもあります) 内の実際の機能は、実行時にデザイナーでは利用できない何かを実際に呼び出します。ファイルの内容は次のようなものでした...

<?xml version="1.0" encoding="utf-16"?>
<Classes xmlns="http://schemas.microsoft.com/VisualStudio/2004/03/SmartDevices/XMTA.xsd">
  <Class Name="MyNamespace.MyControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>

  <Class Name="MyNamespace.MyOtherControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>

  <Class Name="AnotherNamespace.MySignControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>
</Classes>

これは、csauve の回答が提供するコメントに追加されたものでもありました。コンストラクターがデバイスに依存するものを初期化しようとしていて、デザイン時にデバイス dll、コントロール、またはデザイン時にそのコントロールを強制終了する可能性のあるものがないためにエラーがスローされる場合。いずれかの方法でテストするための 2 つの静的関数を作成しました。

public static bool IsDesignTime()
{
  return System.ComponentModel.LicenseManager.UsageMode ==
         System.ComponentModel.LicenseUsageMode.Designtime;
}

public static bool IsRunTime()
{
  return System.ComponentModel.LicenseManager.UsageMode ==
         System.ComponentModel.LicenseUsageMode.Runtime;
}

コンストラクターでそれぞれ呼び出します...

于 2012-04-13T18:54:03.473 に答える
0

おそらく、コントロールがデザインモードになっていることをコントロールに認識させる必要があると思います。回避できる場合は、コントロールのパラメーターなしのコンストラクターが、コストがかかる操作や副作用のある操作(つまり、ディスクからのファイルのロード)を実行しないようにする必要があります。

スクリーンショットから、WPFを使用していると想定しています。デザインモードは、DesignerProperties.GetIsInDesignMode(this)を使用して決定できると思います。http://msdn.microsoft.com/en-us/library/system.componentmodel.designerproperties.getisindesignmode.aspx

を参照してください。

public partial class MyControl : UserControl
{
   public MyControl()
   {
      InitializeComponent();
      if (!DesignerProperties.GetIsInDesignMode(this))
      {
        //Do expensive operations here
      }
   }
}

また、 http://blogs.msdn.com/b/jgalasyn/archive/2007/10/29/troubleshooting-wpf-designer-load-failures.aspxを読んでおくこともできます。

于 2012-04-13T16:44:15.883 に答える