Czy ktoś wie o jakiejś globalnej zmiennej stanu, która jest dostępna, abym mógł sprawdzić, czy kod jest obecnie wykonywany w trybie projektowania (np. W Blend lub Visual Studio), czy nie?
Wyglądałoby to mniej więcej tak:
//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode)
{
...
}
Powód, dla którego tego potrzebuję, jest następujący: kiedy moja aplikacja jest wyświetlana w trybie projektowania w programie Expression Blend, chcę, aby ViewModel zamiast tego używał „klasy Design Customer”, która zawiera makiety danych, które projektant może wyświetlać w trybie projektowania.
Jednak gdy aplikacja jest faktycznie wykonywana, oczywiście chcę, aby ViewModel używał prawdziwej klasy Customer, która zwraca rzeczywiste dane.
Obecnie rozwiązuję ten problem, prosząc projektanta, zanim zacznie nad tym pracować, wchodząc do ViewModel i zmieniając „ApplicationDevelopmentMode.Executing” na „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);
}
}
}
źródło
Enable project code
musi być włączony (lub Menu-> Projekt-> 🗹 Uruchom kod projektu).Możesz zrobić coś takiego:
źródło
internal class MyDependencyObject : DependencyObject {}
i używajnew MyDependencyObject
zamiastDependencyObject
DependencyObject
jestpublic
.Działa z dowolnego miejsca. Używam go, aby zatrzymać odtwarzanie wideo z danymi w projektancie.
źródło
Application.Current.MainWindow == null
chociaż bardziej mi się podoba test typu, bardziej bezpośredni. Wygląda również na to, że projektant hostowany w programie Visual Studio dodaje zasoby, więc oto inny sposób, aby to zrobić (jeśli nie masz dostępu do określonegoApp
typu w bibliotece obsługującej kod)((bool)Application.Current.Resources["ExpressionUseLayoutRounding"])
. Konieczne jest sprawdzenie, czy zasobu nie ma, ale działa w kontekście projektanta.Kiedy Visual Studio automatycznie wygenerował dla mnie jakiś kod, użył
źródło
Istnieją inne (być może nowsze) sposoby określania danych czasu projektowania w WPF, jak wspomniano w tej powiązanej odpowiedzi .
Zasadniczo można określić dane czasu projektowania przy użyciu wystąpienia modelu ViewModel w czasie projektowania :
lub określając przykładowe dane w pliku XAML :
Musisz ustawić
SamplePage.xaml
właściwości pliku na:Umieszczam je w swoim
UserControl
tagu, w ten sposób:W czasie wykonywania wszystkie znaczniki czasu projektowania „d:” znikają, więc będziesz mieć dostęp tylko do kontekstu danych czasu wykonywania, niezależnie od tego, jak go ustawisz.
Edytuj Możesz również potrzebować tych wierszy (nie jestem pewien, ale wydają się istotne):
źródło
A jeśli intensywnie używasz Caliburn.Micro dla swojej dużej aplikacji WPF / Silverlight / WP8 / WinRT , możesz użyć poręcznej i uniwersalnej właściwości
Execute.InDesignMode
statycznej Caliburn również w swoich modelach widoku (i działa w Blend tak dobrze, jak w Visual Studio):źródło
Testowałem to tylko w Visual Studio 2013 i .NET 4.5, ale to załatwia sprawę.
Jest jednak możliwe, że niektóre ustawienia w programie Visual Studio zmienią tę wartość na false, jeśli tak się stanie, możemy po prostu sprawdzić, czy ta nazwa zasobu istnieje. To było,
null
gdy uruchomiłem kod poza projektantem.Zaletą tego podejścia jest to, że nie wymaga ono jawnej znajomości konkretnej
App
klasy i może być używane globalnie w całym kodzie. W szczególności w celu wypełnienia modeli widoków danymi fikcyjnymi.źródło
Zaakceptowana odpowiedź nie działa dla mnie (VS2019).
Po sprawdzeniu, co się dzieje, wymyśliłem to:
źródło
#if DEBUG
inny zwrócony fałsz. Czy jest jakiś powód, żeby tego nie robić?Mam dla Ciebie pomysł, jeśli Twoja klasa nie potrzebuje pustego konstruktora.
Chodzi o to, aby utworzyć pusty konstruktor, a następnie oznaczyć go ObsoleteAttribute. Projektant ignoruje przestarzały atrybut, ale kompilator zgłosi błąd, jeśli spróbujesz go użyć, więc nie ma ryzyka przypadkowego użycia go samodzielnie.
( przepraszam za mój Visual Basic )
A xaml:
To nie zadziała, jeśli naprawdę potrzebujesz pustego konstruktora do czegoś innego.
źródło