DesignMode с вложенными элементами управления - PullRequest
85 голосов
/ 29 августа 2008

Кто-нибудь нашел полезное решение проблемы DesignMode при разработке элементов управления?

Проблема в том, что если вы вкладываете элементы управления, то DesignMode работает только для первого уровня. Второй и нижний уровни DesignMode всегда будут возвращать FALSE.

Стандартным хаком было посмотреть на имя запущенного процесса, и если это "DevEnv.EXE", то он должен быть студийным, поэтому DesignMode действительно TRUE.

Проблема с поиском ProcessName обходится через реестр и другие странные части, в результате чего пользователь может не иметь необходимых прав для просмотра имени процесса. Кроме того, этот странный маршрут очень медленный. Таким образом, нам пришлось накапливать дополнительные хаки, чтобы использовать одиночный код, и если при запросе имени процесса выдается ошибка, тогда предположим, что DesignMode равен FALSE.

Хороший чистый способ определения DesignMode в порядке. Если бы Microsoft исправила это внутренне для фреймворка, было бы еще лучше!

Ответы [ 12 ]

1 голос
/ 29 августа 2008

DesignMode является частной собственностью (из того, что я могу сказать). Ответ заключается в том, чтобы предоставить публичное свойство, которое предоставляет реквизит DesignMode. Затем вы можете создать резервную копию цепочки пользовательских элементов управления, пока не столкнетесь с не пользовательским элементом управления или элементом управления, который находится в режиме разработки. Как то так ....

  public bool RealDesignMode()
  {
     if (Parent is MyBaseUserControl)
     {
        return (DesignMode ? true : (MyBaseUserControl) Parent.RealDesignMode;
     }

     return DesignMode;
  }

Где все ваши UserControls наследуются от MyBaseUserControl. В качестве альтернативы вы можете реализовать интерфейс, который предоставляет «RealDeisgnMode».

Пожалуйста, обратите внимание, что этот код не является живым кодом, он не относится к размышлениям. :)

0 голосов
/ 17 января 2019

Недавно мне пришлось бороться с этой проблемой в Visual Studio 2017 при использовании вложенных элементов UserControls. Я комбинирую несколько подходов, упомянутых выше и в других местах, затем корректирую код, пока у меня не появится достойный метод расширения, который до сих пор работает приемлемо. Он выполняет последовательность проверок, сохраняя результат в статических логических переменных, поэтому каждая проверка выполняется не более одного раза во время выполнения. Процесс может быть излишним, но он препятствует выполнению кода в студии. Надеюсь, это кому-нибудь поможет.

  public static class DesignTimeHelper
  {
    private static bool? _isAssemblyVisualStudio;
    private static bool? _isLicenseDesignTime;
    private static bool? _isProcessDevEnv;
    private static bool? _mIsDesignerHosted; 

    /// <summary>
    ///   Property <see cref="Form.DesignMode"/> does not correctly report if a nested <see cref="UserControl"/>
    ///   is in design mode.  InDesignMode is a corrected that property which .
    ///   (see https://connect.microsoft.com/VisualStudio/feedback/details/553305
    ///   and https://stackoverflow.com/a/2693338/238419 )
    /// </summary>
    public static bool InDesignMode(
      this Control userControl,
      string source = null)
      => IsLicenseDesignTime
         || IsProcessDevEnv
         || IsExecutingAssemblyVisualStudio
         || IsDesignerHosted(userControl);

    private static bool IsExecutingAssemblyVisualStudio
      => _isAssemblyVisualStudio
         ?? (_isAssemblyVisualStudio = Assembly
           .GetExecutingAssembly()
           .Location.Contains(value: "VisualStudio"))
         .Value;

    private static bool IsLicenseDesignTime
      => _isLicenseDesignTime
         ?? (_isLicenseDesignTime = LicenseManager.UsageMode == LicenseUsageMode.Designtime)
         .Value;

    private static bool IsDesignerHosted(
      Control control)
    {
      if (_mIsDesignerHosted.HasValue)
        return _mIsDesignerHosted.Value;

      while (control != null)
      {
        if (control.Site?.DesignMode == true)
        {
          _mIsDesignerHosted = true;
          return true;
        }

        control = control.Parent;
      }

      _mIsDesignerHosted = false;
      return false;
    }

    private static bool IsProcessDevEnv
      => _isProcessDevEnv
         ?? (_isProcessDevEnv = Process.GetCurrentProcess()
                                  .ProcessName == "devenv")
         .Value;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...