WPF'de tasarım zamanı verisi için hangi yaklaşımlar mevcuttur?


97

İfade karışımı olmadan çalışıyorum ve sadece vs2010'da XAML düzenleyicisini kullanıyorum. Bunun bilgeliği bir yana, tasarım zamanında veri bağlama ihtiyacını giderek daha fazla görüyorum. Basit durumlarda, FallbackValueözellik çok iyi çalışır (Metin Kutuları ve Metin Blokları, vb.). Ancak özellikle ItemsControlve benzerleriyle uğraşırken , örnek verilerin tasarımcıda görünür olması gerçekten gerekir, böylece çalıştırılabilir dosyayı çalıştırmak zorunda kalmadan kontrolleri ve veri şablonlarını ayarlayabilir ve değiştirebilirsiniz.

Bunun ObjectDataProviderbir türe bağlanmaya izin verdiğini ve bu nedenle görselleştirme için tasarım zamanı verisi sağlayabileceğini biliyorum , ancak daha sonra gerçek, çalışma zamanı verilerinin hem tasarım süresini hem de yükleyerek kaynakları boşa harcamadan bağlanmasına izin vermek için biraz hokkabazlık var. kukla veriler ve çalışma zamanı bağlamaları.

Gerçekten istediğim şey, diyelim ki "John", "Paul", "George" ve "Ringo" nun XAML tasarımcısında şekillendirilebilir öğeler olarak görünmesi ItemsControl, ancak uygulama sırasında gerçek verilerin görünmesi koşar.

Ayrıca Blend'in, çalışma zamanı koşullarında WPF tarafından etkin bir şekilde göz ardı edilen tasarım zamanı bağlama verilerini tanımlayan bazı süslü özniteliklere izin verdiğini biliyorum.

Yani sorularım:

1. Visual Studio XAML tasarımcısında koleksiyonların ve önemsiz olmayan verilerin tasarım zamanı bağlamalarını nasıl kullanabilirim ve ardından çalışma zamanı bağlamalarına sorunsuz bir şekilde geçiş yapabilirim?

2. Başkaları bu tasarım zamanı ve çalışma zamanı veri sorununu nasıl çözdü? Benim durumumda, aynı verileri her ikisi için de çok kolay kullanamıyorum (örneğin, bir veritabanı sorgusu ile mümkün olabileceği gibi).

3. Veriye entegre XAML tasarımı için kullanabileceğim ifade karışımına alternatifleri var mı? (Bazı alternatifler olduğunu biliyorum, ancak özellikle kullanabileceğim ve bağlı örnek verileri görebileceğim bir şey istiyorum, vb.)

Yanıtlar:


120

VS2010'u kullanarak Tasarım Zamanı niteliklerini kullanabilirsiniz (hem SL hem de WPF için çalışır). Zaten genellikle sahte bir veri kaynağım var, bu yüzden mesele şu:

  • Ad alanı bildirimini ekleme

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    
  • Sahte veri bağlamını pencere / denetim kaynaklarına ekleme

    <UserControl.Resources>
      <ViewModels:MockXViewModel x:Key="DesignViewModel"/>
    </UserControl.Resources>
    
  • Tasarım zamanı veri bağlamını ayarlama

    <Grid d:DataContext="{Binding Source={StaticResource DesignViewModel}}" ...
    

Yeterince iyi çalışıyor.


2
Kullanımda sorun yaşıyorsanız d:DataContext, bu soruda yardım bulabilirsiniz: stackoverflow.com/questions/8303803/…
Martin Liversage

27
Bu örnek, bir MockXViewModel örneğinin bir sürüm derlemesi için kaynaklarınıza yüklenmesine neden olmaz mı? Bu bir endişe değil mi?
jpierson

12
Bilginize: Ayrıca şunlara da ihtiyacınız var, yoksa VS2012 derleyicisi xaml dosyasını derlemeyecek: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"vemc:Ignorable="d"
Orion Edwards

51
jpierson haklı. Kullanmayı tercih ederim <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" .... Bu şekilde, alay edilen görünüm modeli, uygulamanızı çalıştırırken değil, yalnızca tasarımcıda oluşturulacaktır. Bu yaklaşımın sahte görünüm modelinizin parametresiz bir kurucuya sahip olmasını gerektirdiğini unutmayın. Ancak yukarıdaki cevapta verilen örnekte de durum aynıdır.
René

2
@ René yaklaşımınız çok daha iyi. Lütfen bir cevap olarak ekleyin ve ben buna oy vereceğim
dss539

15

Goran'ın kabul ettiği cevabın ve Rene'nin mükemmel yorumunun bir karışımı olarak.

  • Ad alanı bildirimini ekleyin. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

  • Tasarım süresi veri bağlamınıza koddan referans verin.
    <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" ...


1
Bunu yeni cevap olarak işaretlemek beni cezbediyor, ama belki de ayrıntıların geri kalanını çekebiliriz.
el2iot2

Bunun daha fazla görünürlük veya kabul edilen cevaba çekilmesi gerekiyor. Bu çok daha iyi bir çözüm.
Lauraducky

Bu neden daha iyi? İlk başta, kabul edilen cevabın çalışma zamanında da gereksiz yere sahte modeller üreteceğini düşündüm ama bunu test ettim ve aslında öyle değil. Kullanılmadığı takdirde kaynaklar oluşturulmaz.
Paul

@Paul Bu gerçekten bir tercih meselesi, ancak bu cevap, tüm tasarım süresi veri bağlamını tek bir bildirimde ve iki noktada olmasını sağlıyor. Değişiklikleri kolaylaştırır
John Stritenberger

1
@JohnStritenberger Sadece tercih değil, kabul edilen cevap kaynakları gereksiz yere hafızaya yükler, sadece tasarımcı için değil.
UuDdLrLrSs

4

Karl Shifflett, VS2008 ve VS2010 için eşit derecede iyi çalışması gereken bir yaklaşımı anlatıyor:

WPF ve Silverlight Projelerinde Visual Studio 2008 Cider Designer'da Tasarım Zamanı Verilerini Görüntüleme

Laurent Bugnion, Expression Blend'e odaklanan benzer bir yaklaşıma sahiptir. Bu olabilir VS2010 için çalışmak, ama henüz bu teyit etmedi.

Microsoft Expression Blend'de tasarım modunda verileri simüle etme


bunu dikkatime sunduğunuz için teşekkürler. DesignAndRunTimeDataContext konseptini beğendim.
el2iot2

1
Karl Shifflett, Visual Studio 2010 için güncellenmiş bir makaleye sahip: WPF ve Silverlight Tasarımcısında Örnek Veriler
totorocat

1
Bağlantı içeriğinin özü, özellikle ilk bağlantı artık öldüğünden, cevaba gerçekten dönüştürülmelidir.
Lauraducky

4

Belki de Visual Studio 2010 ve Expression Blend 4'ün yeni tasarım zamanı özellikleri sizin için bir seçenektir.

Nasıl çalıştığı, WPF Uygulama Çerçevesinin (WAF) BookLibrary örnek uygulamasında gösterilmektedir . Lütfen .NET4 sürümünü indirin.


Bağlantı için teşekkürler. Yaklaşımı görmek için bakmam gereken belirli bir kod dosyası veya yapı var mı? (kısa bir genel bakış harika olurdu)
el2iot2

BookLibrary.Presentation projesine bir göz atın. Bu projede UserControls tarafından "Görünümler" klasöründe kullanılan "DesignData" klasörünü bulacaksınız.
jbe

1
+1. Şuna bir baktım. İlgili herkes için örnek veri görünümü modeli XAML'de bildirilir ve d: DataContext = "{d: DesignData Source = .. / DesignData / SampleLendToViewModel.xaml}"
RichardOD

4

Bu yaklaşımı .NET 4.5 ve Visual Studio 2013 ile tasarım zamanı verisi oluşturmak için kullanıyorum.

Sadece bir ViewModel'im var. Görünüm modelinin, IsInDesignModetasarım modunun etkin olup olmadığını söyleyen bir özelliği vardır (sınıfa bakınız ViewModelBase). Ardından, görünüm modelleri oluşturucusunda tasarım süresi verilerinizi (bir öğe kontrolünü doldurmak gibi) ayarlayabilirsiniz.

Ayrıca, görünüm modelleri kurucusuna gerçek verileri yüklemem, bu çalışma zamanında sorunlara yol açabilir, ancak tasarım zamanı için veri ayarlamak bir sorun olmamalı.

public abstract class ViewModelBase
{
    public bool IsInDesignMode
    {
        get
        {
            return DesignerProperties.GetIsInDesignMode(new DependencyObject());
        }
    }
}

public class ExampleViewModel : ViewModelBase
{
    public ExampleViewModel()
    {
        if (IsInDesignMode == true)
        {
            LoadDesignTimeData();
        }
    }

    private void LoadDesignTimeData()
    {
        // Load design time data here
    }       
}

4

Ben bu gibi kılavuzlar ve tüm sorulara takip etmeye çalışıyorlar ve hala bir bakıyordu Visual Studio 2017 kullanarak <ItemsControl>basitçe bir yapıcısı içindeki vardı kodu çalıştırmak vermedi hangi DesignFooViewModelden hangi INHERITS FooViewModel. Bu "kullanışlı" MSDN kılavuzunun (spoiler: MessageBoxhata ayıklama) ardından "yürütülmedi" bölümünü onayladım . Bu doğrudan asıl soruyla ilgili olmasa da, umarım başkalarına çok zaman kazandırır.

Yanlış bir şey yapmadığım ortaya çıktı. Sorun, uygulamamın x64 için oluşturulması gerektiğiydi. Gibi Visual Studio 2018 yılında hala 32 bit süreçtir tasarımcı bölümü için 64-bit ana bilgisayar işlemi dönmeye edemez görünüşe ve bu benim x64 sınıfları kullanamazsınız. Gerçekten kötü olan şey, aklıma gelen herhangi bir günlükte bulunabilecek hiçbir hata olmamasıdır.

(Örneğin: Eğer tasarım zamanı görünümü modeli ile de sahte verileri alıyor çünkü Yani bu soruya takılmaları varsa <TextBlock Text="{Binding Name}"/>gösterileri kadar Namehiçbir mülkü set matter) neden olasılıkla x64 inşa olmaktır. Bağımlılıklar nedeniyle derleme yapılandırmanızı herhangi bir cpu veya x86 olarak değiştiremiyorsanız, tamamen herhangi bir cpu olan ve bağımlılıkları (veya herhangi bir bağımlılığı) olmayan yeni bir proje oluşturmayı düşünün. Böylece, kodun başlangıç ​​bölümlerinin çoğunu veya tamamını "WPF Uygulaması" projenizden bir "C # sınıf kitaplığı" projesine bölersiniz.

Üzerinde çalıştığım kod tabanı için bunun, muhtemelen net pozitif bir şey olan bazı kod tekrarları pahasına endişelerin sağlıklı bir şekilde ayrılmasını zorlayacağını düşünüyorum.


3

En çok oy alan yanıta benzer, ancak bence daha iyi: Tasarım verilerinin bir örneğini döndürmek ve ona doğrudan XAML'den aşağıdaki gibi başvurmak için statik bir özellik oluşturabilirsiniz:

<d:UserControl.DataContext>
    <Binding Source="{x:Static designTimeNamespace:DesignTimeViewModels.MyViewModel}" />
</d:UserControl.DataContext>

Bu, kullanma ihtiyacını ortadan kaldırır UserControl.Resources. Statik mülkünüz, önemsiz olmayan veri türleri oluşturmanıza izin veren bir fabrika işlevi görebilir - örneğin, varsayılan bir ctorunuz yoksa, uygun bağımlılıkları enjekte etmek için buradan bir fabrika veya konteyneri çağırabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.