নেস্টেড কন্ট্রোল সহ ডিজাইনমোড


87

নিয়ন্ত্রণগুলি বিকাশে যখন কেউ ডিজাইনমড সমস্যার কার্যকর সমাধান খুঁজে পেয়েছে?

সমস্যাটি হল আপনি যদি নীড় নিয়ন্ত্রণ করেন তবে ডিজাইনমোড কেবল প্রথম স্তরের জন্য কাজ করে। দ্বিতীয় এবং নিম্ন স্তরের ডিজাইনমড সর্বদা মিথ্যা প্রত্যাবর্তন করবে।

স্ট্যান্ডার্ড হ্যাকটি চলছে যে প্রক্রিয়াটির নামটি দেখতে হবে এবং যদি এটি "ডিভিনিভ.এক্সই" হয় তবে এটি অবশ্যই স্টুডিও হতে হবে সুতরাং ডিজাইনমোডটি সত্যই সত্য।

প্রসেসনামটির সন্ধান করা সমস্যাটি শেষ ফলাফল সহ রেজিস্ট্রি এবং অন্যান্য অদ্ভুত অংশগুলির মধ্য দিয়ে কাজ করে যাতে ব্যবহারকারীর প্রক্রিয়াটির নাম দেখার প্রয়োজনীয় অধিকার নাও থাকতে পারে। এছাড়াও এই অদ্ভুত রুটটি খুব ধীর। সুতরাং একটি সিঙ্গলটন ব্যবহার করতে আমাদের অতিরিক্ত হ্যাকগুলি স্তূপিত করতে হয়েছিল এবং প্রক্রিয়াটির নাম জিজ্ঞাসা করার সময় যদি কোনও ত্রুটি ছুঁড়ে দেওয়া হয় তবে ধরে নিন যে ডিজাইনমোডটি মিথ্যা।

ডিজাইনমোড নির্ধারণের জন্য একটি দুর্দান্ত পরিষ্কার উপায় ক্রমানুসারে। মাইক্রোসফ্টকে ফ্রেমওয়ার্কে অভ্যন্তরীণভাবে ঠিক করার জন্য এটি আরও ভাল হবে!



8
"ফ্রেমওয়ার্কে মাইক্রোসফ্টকে অভ্যন্তরীণভাবে এটি ঠিক করা আরও ভাল হবে" এর জন্য +1 - কারও দশ মিনিটের সময় কয়েক হাজার লোককে কয়েক ঘন্টা বাঁচাতে পারে। যদি এমন কোনও প্রোগ্রাম থাকে যা বাগের উপর নির্ভর করে এবং এটি দ্বারা অসুবিধাগুলি রয়েছে এমন 100,000, তবে কোনও প্রোগ্রামের অসুবিধা এড়াতে বাগটি রাখা কোনও অর্থ হয় না!
ব্লুরাজা - ড্যানি পিফ্লুঘুফ্ট

হাই, এটি ২০০৮ সালে পোস্ট করা হয়েছিল this এখন এটি স্থির?
জেক

ভিএস ২০১২ সালে এটি এখন একইরকম থেকে যায়
বুগিয়ার

4
মনে রাখবেন যে যদি ইউজারকন্ট্রোলের জন্য কাস্টম ডিজাইনার ব্যবহার করা হয় (উদাহরণস্বরূপ, আমি কন্ট্রোল ডিজাইনার থেকে প্রাপ্ত ক্লাসের সাথে পরীক্ষা করেছি), তবে সক্ষম ডিজাইনমোড (সাবকন্ট্রোল) কল করা সাবকন্ট্রোল কাজের ডিজাইনমোড সম্পত্তি বলে মনে হয়। এটি সমস্যার কার্যকর সমাধান নয় তবে আমরা সবসময় আমাদের নিয়ন্ত্রণ রাখার ধারকটি লেখি না।
প্রোটংগন

উত্তর:


81

এই প্রশ্নের পুনর্বিবেচনা করা, আমি এখন এটি করার 5 টি ভিন্ন উপায় 'আবিষ্কার' করেছি, যা নীচে রয়েছে:

System.ComponentModel.DesignMode property

System.ComponentModel.LicenseManager.UsageMode property

private string ServiceString()
{
    if (GetService(typeof(System.ComponentModel.Design.IDesignerHost)) != null) 
        return "Present";
    else
        return "Not present";
}

public bool IsDesignerHosted
{
    get
    {
        Control ctrl = this;

        while(ctrl != null)
        {
            if((ctrl.Site != null) && ctrl.Site.DesignMode)
                return true;
            ctrl = ctrl.Parent;
        }
        return false;
    }
}
public static bool IsInDesignMode()
{
    return System.Reflection.Assembly.GetExecutingAssembly()
         .Location.Contains("VisualStudio"))
}

প্রস্তাবিত তিনটি সমাধানের জন্য চেষ্টা করতে এবং ফাঁসি পেতে, আমি তিনটি প্রকল্প সহ একটি সামান্য পরীক্ষার সমাধান তৈরি করেছি:

  • টেস্ট অ্যাপ (উইনফর্মস অ্যাপ্লিকেশন),
  • সাবকন্ট্রোল (ডিএল)
  • সাবসব্যাক্ট্রোল (dll)

আমি তারপরে সাবকন্ট্রোলটিতে সাবসব্যাক্ট্রোল এম্বেড করেছি, তারপরে টেস্ট অ্যাপ.ফর্মের প্রতিটি একটি one

এই স্ক্রিনশটটি চলমান অবস্থায় ফলাফলটি দেখায়। চলমান স্ক্রিনশট

এই স্ক্রিনশটটি ভিজ্যুয়াল স্টুডিওতে খোলা ফর্মের সাথে ফলাফলটি দেখায়:

চলছে না এর স্ক্রিনশট

উপসংহার: এটি প্রদর্শিত হবে যে প্রতিবিম্ব ছাড়াই কেবল নির্মাণকারীর মধ্যে নির্ভরযোগ্য কেবল লাইসেন্সসেজ, এবং নির্মাণকারীর বাইরে নির্ভরযোগ্য একমাত্র হ'ল 'ইসডিজাইনহোস্টেড' ( নীচের নীলরাজ দ্বারা )

পিএস: নীচে টুল মেকস্টেভের মন্তব্য দেখুন (যা আমি পরীক্ষা করি নি): "নোট করুন যে আইসডিজাইনারহোস্টেড উত্তরটি লাইসেন্সউসেজ অন্তর্ভুক্ত করার জন্য আপডেট করা হয়েছে ... সুতরাং এখন পরীক্ষাটি কেবল যদি (ইসডিজাইনারহোস্টেড) হতে পারে তবে কনস্ট্রাক্টরে একটি বিকল্প পদ্ধতির লাইসেন্স লাইসেন্স ম্যানেজার হয় এবং ফলাফলটি ক্যাশে করুন


@ বেঞ্জল: ইসডিজাইনার হোস্টেড (নীচে) সম্পর্কে কী? (এছাড়াও, আমি মনে করি আপনার নকশা-সময় এবং রানটাইম অদলবদল হয়েছে, রানটাইমের সময় এটি কী বলেছে তা পরীক্ষা করে দেখুন)
ব্লুরাজা - ড্যানি ফ্লুঘুফুট

@ ব্লুরাজা, আমার অবশ্যই এই প্রকল্পটি অবশ্যই ডিস্কের কোথাও পড়ে থাকতে পারে, সম্ভবত আমার এটি অন্য কোথাও পোস্ট করা উচিত ...
বেনজল

4
একটি অভিজ্ঞতা অভিজ্ঞতা দ্বারা স্পষ্টকরণের জন্য +1। @ বেঞ্জল, যদি আপনি এটি পুনর্বিবেচনার সুযোগ পান তবে আপনি নিজেই ফর্মের মূল্যবোধগুলির জন্য একটি মামলা যুক্ত করতে পারেন যেহেতু ডিজাইনারে সম্পাদিত শ্রেণীর চেয়ে শিশু নিয়ন্ত্রণগুলি অন্যরকম আচরণ করা যেতে পারে। (দ্রষ্টব্য যে সম্পাদনা করা শ্রেণীর কন্সট্রাক্টর ডিজাইনারে কার্যকর করা হয় না))
রব পার্কার

4
সুতরাং, প্রতিবিম্ব ছাড়া if(LicenseUseage == LicenseUsageMode.Designtime || IsDesignerHosted)100% সঠিক পদ্ধতির হবে?
স্কট চেম্বারলাইন

4
নোট করুন যে IsDesignerHosted উত্তর অন্তর্ভুক্ত করার জন্য আপডেট করা হয়েছে LicenseUsage..., তাই এখন পরীক্ষা সহজভাবে হতে পারে if (IsDesignerHosted)। একটি বিকল্প পদ্ধতির কনস্ট্রাক্টর পরীক্ষার লাইসেন্সম্যানেজার এবং ফলাফলটি ক্যাশে করা
নির্মাতা

32

থেকে এই পৃষ্ঠা :

( [২০১৩ সম্পাদনা করুন] @ হপলা প্রদত্ত পদ্ধতিটি ব্যবহার করে কনস্ট্রাক্টরে কাজ করার জন্য সম্পাদিত)

/// <summary>
/// The DesignMode property does not correctly tell you if
/// you are in design mode.  IsDesignerHosted is a corrected
/// version of that property.
/// (see https://connect.microsoft.com/VisualStudio/feedback/details/553305
/// and http://stackoverflow.com/a/2693338/238419 )
/// </summary>
public bool IsDesignerHosted
{
    get
    {
        if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
            return true;

        Control ctrl = this;
        while (ctrl != null)
        {
            if ((ctrl.Site != null) && ctrl.Site.DesignMode)
                return true;
            ctrl = ctrl.Parent;
        }
        return false;
    }
}

আমি মাইক্রোসফ্টের সাথে একটি বাগ-রিপোর্ট জমা দিয়েছি ; আমি সন্দেহ করি এটি যে কোনও জায়গায় যাবে, তবে যেকোন উপায়েই এটির ভোট দিন, কারণ এটি স্পষ্টতই একটি বাগ (এটি "ডিজাইনের দ্বারা" হোক না কেন )।


29

আপনি লাইসেন্সম্যানেজ.উসেজমোড চেক করবেন না কেন। এই সম্পত্তির লাইসেন্সসইউজমোড.রুনটাইম বা লাইসেন্সউসেজডমড.ডিজাইনটাইম মান থাকতে পারে।

আপনি কি কোডটি কেবল রানটাইম চলতে চান, নিম্নলিখিত কোডটি ব্যবহার করুন:

if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
{
  bla bla bla...
}

8
+1 আমি এটি ব্যবহার করেছি। লোকেরা কী ট্রিপ করে তা হ'ল ডিজাইনমড কোনও কনস্ট্রাক্টরে কাজ করবে না।
নিকোলাস পাইসেকি

4
@ নিকোলাস: এটি শিশু নিয়ন্ত্রণেও কাজ করে না। এটি কেবল ভাঙা।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

+1 - এটি একটি উদ্ভূত নিয়ন্ত্রণের ডিজাইনের সময় নির্মিত বেস নিয়ন্ত্রণগুলিতেও কাজ করে।
এমসিডব্লিউ

7

এই পদ্ধতিটি আমি অভ্যন্তরের ফর্মগুলি ব্যবহার করি:

    /// <summary>
    /// Gets a value indicating whether this instance is in design mode.
    /// </summary>
    /// <value>
    ///     <c>true</c> if this instance is in design mode; otherwise, <c>false</c>.
    /// </value>
    protected bool IsDesignMode
    {
        get { return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime; }
    }

এইভাবে, ফলাফলটি সঠিক হবে, এমনকি ডিজাইনমড বা লাইসেন্সম্যানেজারের কোনও বৈশিষ্ট্য ব্যর্থ হলেও।


4
হ্যাঁ, আপনি যেমন বলছেন তেমন এটি ফর্মগুলিতে কাজ করবে। তবে আমি এটি উল্লেখ করতে চাই যে নাতি-নাতি ব্যবহারকারীর নিয়ন্ত্রণে কনস্ট্রাক্টরের বাইরে কাজ করে না।
অ্যালো

5

আমি লাইসেন্সম্যানেজার পদ্ধতিটি ব্যবহার করি তবে উদাহরণটির আজীবন ব্যবহারের জন্য নির্মাতার কাছ থেকে মানটি ক্যাশে করি

public MyUserControl()
{
    InitializeComponent();
    m_IsInDesignMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
}

private bool m_IsInDesignMode = true;
public bool IsInDesignMode { get { return m_IsInDesignMode; } }

ভিবি সংস্করণ:

Sub New()
    InitializeComponent()

    m_IsInDesignMode = (LicenseManager.UsageMode = LicenseUsageMode.Designtime)
End Sub

Private ReadOnly m_IsInDesignMode As Boolean = True
Public ReadOnly Property IsInDesignMode As Boolean
    Get
        Return m_IsInDesignMode
    End Get
End Property

4
জোনাথন, আমি আপনার উত্তরে একটি (পরীক্ষিত) ভিবি সংস্করণ যুক্ত করেছি।
টুলমেকারস্টেভ

3

আমরা সাফল্যের সাথে এই কোডটি ব্যবহার করি:

public static bool IsRealDesignerMode(this Control c)
{
  if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
    return true;
  else
  {
    Control ctrl = c;

    while (ctrl != null)
    {
      if (ctrl.Site != null && ctrl.Site.DesignMode)
        return true;
      ctrl = ctrl.Parent;
    }

    return System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv";
  }
}

3

আমার পরামর্শটি হ'ল ব্লুরাজা-ড্যানি-পিফ্লুঘুফুট জবাবের একটি অপ্টিমাইজেশন । এই সমাধানটি প্রতিবার ফলাফল গণনা করে না তবে কেবল প্রথম সময়ে (কোনও বস্তু ইউজেজোডকে ডিজাইন থেকে রানটাইম পর্যন্ত পরিবর্তন করতে পারে না)

private bool? m_IsDesignerHosted = null; //contains information about design mode state
/// <summary>
/// The DesignMode property does not correctly tell you if
/// you are in design mode.  IsDesignerHosted is a corrected
/// version of that property.
/// (see https://connect.microsoft.com/VisualStudio/feedback/details/553305
/// and https://stackoverflow.com/a/2693338/238419 )
/// </summary>
[Browsable(false)]
public bool IsDesignerHosted
{
    get
    {
        if (m_IsDesignerHosted.HasValue)
            return m_IsDesignerHosted.Value;
        else
        {
            if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
            {
                m_IsDesignerHosted = true;
                return true;
            }
            Control ctrl = this;
            while (ctrl != null)
            {
                if ((ctrl.Site != null) && ctrl.Site.DesignMode)
                {
                    m_IsDesignerHosted = true;
                    return true;
                }
                ctrl = ctrl.Parent;
            }
            m_IsDesignerHosted = false;
            return false;
        }
    }
}

আপনি যদি কোনও মান ক্যাশে যাচ্ছেন তবে এই জটিলতায় যাওয়ার কোনও কারণ নেই। পরিবর্তে, ব্যবহার যোনাথনের উত্তর , যা সহজ LicenseManager পরীক্ষা ব্যবহার কন্সট্রাকটর মধ্যে , ফলে ক্যাশে।
নির্মাতা

আমি মনে করি এই পদ্ধতির সুবিধাটি হ'ল, এমনকি এটিকে এমনকি লাইসেন্সর ম্যানেজার পরীক্ষারও প্রয়োজন হয় না, যদি কোনও ক্ষেত্রে সম্পত্তিটির কখনও প্রয়োজন হয় না।
সেবাস্তিয়ান ওয়ার্ক

2

আমি নিজেও এটিকে কখনও ধরা পড়িনি, তবে আপনি কি নিয়ন্ত্রণের বাইরে প্যারেন্ট চেইনটি ব্যাক আপ করতে পারবেন না যে ডিজাইনমোড আপনার উপরে কোথাও সেট করা আছে কিনা তা দেখতে?


2

যেহেতু কোনও পদ্ধতি নির্ভরযোগ্য নয় (ডিজাইনমোড, লাইসেন্সম্যানেজার) বা দক্ষ (প্রক্রিয়া, পুনরাবৃত্ত চেক) আমি public static bool Runtime { get; private set }প্রোগ্রাম পর্যায়ে একটি ব্যবহার করছি এবং এটি স্পষ্টভাবে মেইন () পদ্ধতির অভ্যন্তরে সেট করছি।


1

ডিজাইনমোড একটি ব্যক্তিগত সম্পত্তি (আমি যা বলতে পারি তা থেকে)। উত্তরটি হ'ল একটি সর্বজনীন সম্পত্তি সরবরাহ করা যা ডিজাইনমোড প্রপোসটি প্রকাশ করে। তারপরে আপনি ব্যবহারকারীর নিয়ন্ত্রণের শৃঙ্খলা ব্যাক আপ করতে পারবেন যতক্ষণ না আপনি অ-ব্যবহারকারী নিয়ন্ত্রণ বা ডিজাইনের মোডে থাকা কোনও নিয়ন্ত্রণে না চলে। এটার মতো কিছু....

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

     return DesignMode;
  }

যেখানে আপনার সমস্ত ব্যবহারকারীর নিয়ন্ত্রণগুলি মাইবেসউসারকন্ট্রোল থেকে উত্তরাধিকারী। বিকল্পভাবে আপনি এমন একটি ইন্টারফেস প্রয়োগ করতে পারেন যা "রিয়েলডিজনমোড" প্রকাশ করে।

দয়া করে নোট করুন যে এই কোডটি লাইভ কোড নয়, কেবল কাফের সংগীত ছাড়াই। :)


1

আমি বুঝতে পারি নি যে আপনি পিতামাতাকে কল করতে পারবেন না es ডিজাইনমোড (এবং আমি সি # তেও 'সুরক্ষিত' সম্পর্কে কিছু শিখেছি ...)

এখানে একটি প্রতিবিম্বিত সংস্করণ রয়েছে: (আমি সন্দেহ করি যে ডিজাইনমোডপ্রোটটি একটি স্ট্যাটিক ক্ষেত্র তৈরির ক্ষেত্রে পারফরম্যান্সের সুবিধা হতে পারে)

static bool IsDesignMode(Control control)
{
    PropertyInfo designModeProperty = typeof(Component).
      GetProperty("DesignMode", BindingFlags.Instance | BindingFlags.NonPublic);

    while (designModeProperty != null && control != null)
    {
        if((bool)designModeProperty.GetValue(control, null))
        {
            return true;
        }
        control = control.Parent;
    }
    return false;
}

0

নেস্টেড ইউজারকন্ট্রোলগুলি ব্যবহার করার সময় আমাকে সম্প্রতি ভিজ্যুয়াল স্টুডিও 2017 এ এই সমস্যার লড়াই করতে হয়েছিল। আমি উপরে এবং অন্যত্র উল্লিখিত কয়েকটি পদ্ধতির একত্রিত করেছি, তারপরে কোডটি ট্যুইক করেছি যতক্ষণ না আমার একটি শালীন এক্সটেনশন পদ্ধতি রয়েছে যা এ পর্যন্ত গ্রহণযোগ্যভাবে কাজ করে। এটি চেকগুলির ক্রম সম্পাদন করে স্ট্যাটিক বুলিয়ান ভেরিয়েবলগুলিতে ফলাফল সংরক্ষণ করে যাতে প্রতিটি চেক রান সময়ে কেবলমাত্র একবারে সঞ্চালিত হয়। প্রক্রিয়াটি ওভারকিল হতে পারে, তবে এটি স্টুডিওতে সম্পাদন করা থেকে কোড রাখছে। আশা করি এটি কাউকে সাহায্য করবে।

  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;
  }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.