क्या यह जांचने का कोई तरीका है कि वर्तमान में WPF डिजाइन मोड में चल रहा है या नहीं?


147

क्या किसी को कुछ वैश्विक राज्य चर के बारे में पता है जो उपलब्ध है ताकि मैं यह जांच कर सकूं कि कोड वर्तमान में डिजाइन मोड (जैसे ब्लेंड या विजुअल स्टूडियो) में निष्पादित हो रहा है या नहीं?

यह कुछ इस तरह दिखेगा:

//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode) 
{
    ...
}

मुझे इसकी आवश्यकता है: जब मेरा आवेदन अभिव्यक्ति मिश्रण में डिज़ाइन मोड में दिखाया जा रहा है, तो मैं चाहता हूं कि ViewModel इसके बजाय एक "डिज़ाइन ग्राहक वर्ग" का उपयोग करें, जिसमें इसमें नकली डेटा है जिसे डिज़ाइनर डिज़ाइन मोड में देख सकता है।

हालाँकि, जब एप्लिकेशन वास्तव में निष्पादित हो रहा है, तो मैं निश्चित रूप से ViewModel को वास्तविक ग्राहक वर्ग का उपयोग करना चाहता हूं जो वास्तविक डेटा लौटाता है।

वर्तमान में मैं डिजाइनर होने से इसे हल करता हूं, इससे पहले कि वह इस पर काम करता है, ViewModel में जाएं और "ApplicationDevelopmentMode.Executing" को "ApplicationDevelopmentMode.Designing" में बदल दें:

public CustomersViewModel()
{
    _currentApplicationDevelopmentMode = ApplicationDevelopmentMode.Designing;
}

public ObservableCollection<Customer> GetAll
{
    get
    {
        try
        {
            if (_currentApplicationDevelopmentMode == ApplicationDevelopmentMode.Developing)
            {
                return Customer.GetAll;
            }
            else
            {
                return CustomerDesign.GetAll;
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
    }
}

जवाबों:


226

मेरा मानना ​​है कि आप GetIsInDesignMode की तलाश कर रहे हैं , जो एक डिपेंडेंसी ऑबजेक्ट लेता है।

अर्थात।

// 'this' is your UI element
DesignerProperties.GetIsInDesignMode(this);

संपादित करें: सिल्वरलाइट / WP7 का उपयोग करते समय, आपको IsInDesignToolतब उपयोग करना चाहिए, जब GetIsInDesignModeकभी-कभी दृश्य स्टूडियो में झूठे वापस आ सकते हैं:

DesignerProperties.IsInDesignTool

संपादित करें: और अंत में, पूर्णता के हित में, WinRT / मेट्रो / विंडोज स्टोर अनुप्रयोगों में समतुल्य है DesignModeEnabled:

Windows.ApplicationModel.DesignMode.DesignModeEnabled

3
एक साइड नोट के रूप में, IsInDesignMode वास्तव में एक संलग्न संपत्ति है, इसलिए आप इसे xaml से भी बाध्यकारी में उपयोग कर सकते हैं। हालांकि सबसे आम उपयोग नहीं हो सकता है :)
aL3891

3
WinRT और WP जैसे नवीनतम XAML "एप्लिकेशन" के साथ उत्तर को अपडेट रखने के लिए धन्यवाद।
सेवन करें

VS2019 में स्विच Enable project codeसक्षम होना चाहिए (या मेनू-> डिज़ाइन->) रन प्रोजेक्ट कोड)।
मारबेल 82

115

आप ऐसा कुछ कर सकते हैं:

DesignerProperties.GetIsInDesignMode(new DependencyObject());

30
यह विधि ViewModels को डिज़ाइनर-फ्रेंडली बनाने के लिए भी काम करती है (क्योंकि वे DependencyObjects स्वयं नहीं हैं)।
पैट

1
निर्भरताओबजेक्ट में एक संरक्षित कंस्ट्रक्टर है - परिभाषित करें internal class MyDependencyObject : DependencyObject {}और new MyDependencyObjectइसके बजाय उपयोग करेंDependencyObject
रीको Suter


यदि आप एक दृश्यदर्शी में ऐसा कर रहे हैं, तो आप शायद इसे एक स्थिर वर्ग में बदल देना चाहते हैं और एक स्थिर बूलियन के रूप में परिणाम को स्टोर कर सकते हैं
सिमोन_विवर

24
public static bool InDesignMode()
{
    return !(Application.Current is App);
}

कहीं से भी काम करता है। मैं इसे डिजाइनर में खेलने से डेटाबाउंड वीडियो को रोकने के लिए उपयोग करता हूं।


उपरोक्त पर एक भिन्नता Application.Current.MainWindow == nullहालांकि मुझे टाइप टेस्ट बेहतर, अधिक प्रत्यक्ष पसंद है। ऐसा भी प्रतीत होता है जैसे कि Visual Studio में होस्ट किया गया डिज़ाइनर संसाधनों को जोड़ता है, इसलिए यहां ऐसा करने का एक और तरीका है (यदि आपके पास Appअपने कोड की मेजबानी करने वाले पुस्तकालय में विशिष्ट प्रकार तक पहुंच नहीं है ) ((bool)Application.Current.Resources["ExpressionUseLayoutRounding"])। अगर संसाधन नहीं है, तो जांच की जरूरत है, लेकिन यह डिजाइनर संदर्भ में काम करता है।
जॉन लेडिग्रेन

9

जब विजुअल स्टूडियो ऑटो ने मेरे लिए कुछ कोड का उपयोग किया था

if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) 
{
    ...
}

9

WPF में डिज़ाइन-टाइम डेटा निर्दिष्ट करने के अन्य (शायद नए) तरीके हैं, जैसा कि इस संबंधित उत्तर में बताया गया है

अनिवार्य रूप से, आप अपने ViewModel के डिज़ाइन-टाइम उदाहरण का उपयोग करके डिज़ाइन-टाइम डेटा निर्दिष्ट कर सकते हैं :

d:DataContext="{d:DesignInstance Type=v:MySampleData, IsDesignTimeCreatable=True}"

या XAML फ़ाइल में नमूना डेटा निर्दिष्ट करके :

d:DataContext="{d:DesignData Source=../DesignData/SamplePage.xaml}">

आपको SamplePage.xamlफ़ाइल के गुण सेट करने होंगे:

BuildAction:               DesignData
Copy to Output Directory:  Do not copy
Custom Tool:               [DELETE ANYTHING HERE SO THE FIELD IS EMPTY]

मैं इन्हें UserControlइस तरह अपने टैग में रखता हूं :

<UserControl
    ...
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    ...
    d:DesignWidth="640" d:DesignHeight="480"
    d:DataContext="...">

रन-टाइम पर, सभी "डी:" डिज़ाइन-टाइम टैग गायब हो जाते हैं, इसलिए आपको केवल अपना रन-टाइम डेटा संदर्भ मिलेगा, हालांकि आप इसे सेट करना चुनते हैं।

संपादित करें आपको इन लाइनों की भी आवश्यकता हो सकती है (मैं निश्चित नहीं हूं, लेकिन वे प्रासंगिक लगते हैं):

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 

7

और यदि आप अपने बड़े WPF / Silverlight / WP8 / WinRT एप्लिकेशन के लिए बड़े पैमाने पर Caliburn.Micro का उपयोग करते हैं, तो आप अपने दृश्य-मॉडल में भी आसान और सार्वभौमिक कैलिबर की स्थिर संपत्ति का उपयोग कर सकते हैं (और यह ब्लेंड में विजुअल स्टूडियो में भी अच्छा काम करता है):Execute.InDesignMode

using Caliburn.Micro;

// ...

/// <summary>
/// Default view-model's ctor without parameters.
/// </summary>
public SomeViewModel()
{
    if(Execute.InDesignMode)
    {
        //Add fake data for design-time only here:

        //SomeStringItems = new List<string>
        //{
        //  "Item 1",
        //  "Item 2",
        //  "Item 3"
        //};
    }
}

2

मैंने इसे केवल Visual Studio 2013 और .NET 4.5 के साथ परीक्षण किया है, लेकिन यह ट्रिक करता है।

public static bool IsDesignerContext()
{
  var maybeExpressionUseLayoutRounding =
    Application.Current.Resources["ExpressionUseLayoutRounding"] as bool?;
  return maybeExpressionUseLayoutRounding ?? false;
}

हालांकि यह संभव है कि विज़ुअल स्टूडियो में कुछ सेटिंग इस मान को असत्य में बदल दें, अगर ऐसा कभी होता है तो हम केवल जाँच कर सकते हैं कि क्या यह संसाधन नाम मौजूद है। यह nullतब था जब मैंने डिजाइनर के बाहर अपना कोड चलाया था ।

इस दृष्टिकोण का उल्टा यह है कि इसके लिए विशिष्ट Appवर्ग के स्पष्ट ज्ञान की आवश्यकता नहीं होती है और इसका उपयोग आपके कोड में विश्व स्तर पर किया जा सकता है। विशेष रूप से डमी डेटा के साथ दृश्य मॉडल को पॉप्युलेट करने के लिए।


2

स्वीकृत जवाब मेरे (VS2019) काम नहीं आया।

जो कुछ चल रहा था उसका निरीक्षण करने के बाद, मैं इसे लेकर आया:

    public static bool IsRunningInVisualStudioDesigner
    {
        get
        {
            // Are we looking at this dialog in the Visual Studio Designer or Blend?
            string appname = System.Reflection.Assembly.GetEntryAssembly().FullName;
            return appname.Contains("XDesProc");
        }
    }

यह मेरे लिए काम करता है जहां मुझे यह जानने की जरूरत है कि क्या मैं एक viewModel के भीतर से डिजाइन समय में चल रहा था और विंडोज पुस्तकालयों का उपयोग नहीं कर सकता था। मुझे पता है कि यह बहुत कम मात्रा में प्रतिबिंब है, लेकिन मुझे इसके उत्पादन में भाग लेने के बारे में सोचना पसंद नहीं था, इसलिए मैंने इस कोड को एक #if DEBUGऔर रिटर्न में लिपट दिया । क्या ऐसा न करने का कोई कारण है?
टॉबी स्मिथ

1

अगर आपके वर्ग को एक खाली कंस्ट्रक्टर की आवश्यकता नहीं है, तो मुझे आपके लिए एक विचार है।

विचार एक खाली कंस्ट्रक्टर बनाने का है, फिर इसे अप्रत्यक्ष रूप से चिह्नित करें। डिजाइनर अप्रचलित विशेषता को नजरअंदाज करता है, लेकिन यदि आप इसे उपयोग करने का प्रयास करते हैं, तो संकलक एक त्रुटि उठाएगा, इसलिए इसे स्वयं का उपयोग करने से दुर्घटना का कोई खतरा नहीं है।

( माई विजुअल बेसिक माफ करें )

Public Class SomeClass

    <Obsolete("Constructor intended for design mode only", True)>
    Public Sub New()
        DesignMode = True
        If DesignMode Then
            Name = "Paula is Brillant"
        End If
    End Sub

    Public Property DesignMode As Boolean
    Public Property Name As String = "FileNotFound"
End Class

और xaml:

<UserControl x:Class="TestDesignMode"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:vm="clr-namespace:AssemblyWithViewModels;assembly=AssemblyWithViewModels"
             mc:Ignorable="d" 
             >
  <UserControl.Resources>
    <vm:SomeClass x:Key="myDataContext" />
  </UserControl.Resources>
  <StackPanel>
    <TextBlock d:DataContext="{StaticResource myDataContext}" Text="{Binding DesignMode}" Margin="20"/>
    <TextBlock d:DataContext="{StaticResource myDataContext}" Text="{Binding Name}" Margin="20"/>
  </StackPanel>
</UserControl>

उपरोक्त कोड का परिणाम

यह काम नहीं करेगा अगर आपको वास्तव में किसी और चीज़ के लिए खाली कंस्ट्रक्टर की आवश्यकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.