มีแนวทางใดบ้างสำหรับข้อมูลเวลาออกแบบจำลองใน WPF


97

ฉันกำลังทำงานโดยไม่มีการผสมผสานนิพจน์และใช้ตัวแก้ไข XAML ใน vs2010 นอกเหนือจากภูมิปัญญานี้แล้วฉันก็เห็นความจำเป็นในการผูกข้อมูลเวลาออกแบบมากขึ้น สำหรับกรณีง่ายๆFallbackValueคุณสมบัตินี้ใช้งานได้ดีมาก (Textboxes และ TextBlocks ฯลฯ ) แต่โดยเฉพาะอย่างยิ่งเมื่อต้องจัดการกับItemsControlสิ่งที่คล้ายกันเราต้องการข้อมูลตัวอย่างเพื่อให้มองเห็นได้ในตัวออกแบบเพื่อให้คุณสามารถปรับและปรับแต่งการควบคุมและเทมเพลตข้อมูลโดยไม่ต้องเรียกใช้ไฟล์ปฏิบัติการ

ฉันรู้ว่าObjectDataProviderอนุญาตให้ผูกกับประเภทและทำให้สามารถให้ข้อมูลเวลาออกแบบสำหรับการแสดงภาพได้ แต่ก็มีการเล่นกลเพื่อให้ข้อมูลเรียลไทม์สามารถผูกได้โดยไม่ต้องเสียทรัพยากรโดยการโหลดโหลดทั้งเวลาออกแบบ ข้อมูลจำลองและการเชื่อมโยงรันไทม์

สิ่งที่ฉันต้องการจริงๆคือความสามารถในการมีพูด "จอห์น" "พอล" "จอร์จ" และ "ริงโก" ปรากฏในตัวออกแบบ XAML เป็นรายการที่มีสไตล์ในของฉันItemsControlแต่ข้อมูลจริงจะปรากฏขึ้นเมื่อแอปพลิเคชัน วิ่ง

ฉันรู้ด้วยว่า Blend อนุญาตให้มีคุณสมบัติแฟนซีบางอย่างที่กำหนดข้อมูลการผูกเวลาออกแบบที่ WPF ละเลยอย่างมีประสิทธิภาพในเงื่อนไขรันไทม์

ดังนั้นคำถามของฉันคือ:

1. ฉันจะใช้ประโยชน์จากการเชื่อมโยงเวลาออกแบบของคอลเลกชันและข้อมูลที่ไม่สำคัญในตัวออกแบบ XAML ของ Visual Studio แล้วเปลี่ยนไปใช้การเชื่อมโยงรันไทม์ได้อย่างไร

2. ผู้อื่นแก้ไขปัญหาข้อมูลเวลาออกแบบเทียบกับรันไทม์นี้อย่างไร ในกรณีของฉันฉันไม่สามารถใช้ข้อมูลเดียวกันสำหรับทั้งสองอย่างได้อย่างง่ายดาย (เช่นเดียวกับที่สามารถทำได้ด้วยเช่นการสืบค้นฐานข้อมูล)

3. ทางเลือกอื่นในการผสมผสานนิพจน์ที่ฉันสามารถใช้สำหรับการออกแบบ XAML ที่รวมข้อมูลได้หรือไม่ (ฉันรู้ว่ามีทางเลือกอื่น แต่ฉันต้องการบางอย่างที่ฉันสามารถใช้ได้และดูข้อมูลตัวอย่างที่ถูกผูกไว้ ฯลฯ )

คำตอบ:


120

การใช้ VS2010 คุณสามารถใช้แอตทริบิวต์เวลาออกแบบ (ใช้ได้กับทั้ง SL และ WPF) ฉันมักจะมีแหล่งข้อมูลจำลองอยู่แล้วดังนั้นจึงเป็นเพียงเรื่องของ:

  • การเพิ่มการประกาศเนมสเปซ

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    
  • การเพิ่มบริบทข้อมูลจำลองให้กับทรัพยากรหน้าต่าง / การควบคุม

    <UserControl.Resources>
      <ViewModels:MockXViewModel x:Key="DesignViewModel"/>
    </UserControl.Resources>
    
  • การตั้งค่าบริบทข้อมูลเวลาออกแบบ

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

ทำงานได้ดีพอ


2
หากคุณประสบปัญหาในการใช้งานd:DataContextคุณอาจพบความช่วยเหลือในคำถามนี้: stackoverflow.com/questions/8303803/…
Martin Liversage

27
ตัวอย่างนี้จะไม่ทำให้อินสแตนซ์ของ MockXViewModel ถูกโหลดลงในทรัพยากรของคุณเพื่อสร้างรุ่นหรือไม่? นี่ไม่น่ากังวลหรือ?
jpierson

12
FYI: คุณต้องมีสิ่งต่อไปนี้ไม่เช่นนั้นคอมไพเลอร์ VS2012 จะไม่คอมไพล์ไฟล์ xaml: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"และmc:Ignorable="d"
Orion Edwards

51
jpierson พูดถูก <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" ...ฉันชอบที่จะใช้ ด้วยวิธีนี้ Viewmodel จำลองจะถูกสร้างขึ้นในตัวออกแบบเท่านั้นไม่ใช่ในขณะที่เรียกใช้แอปพลิเคชัน โปรดจำไว้ว่าแนวทางนี้ต้องการให้โมเดลมุมมองจำลองของคุณมีตัวสร้างแบบไม่มีพารามิเตอร์ แต่ก็เหมือนกันในตัวอย่างที่ให้ไว้ข้างต้นในคำตอบ
René

2
@ Renéแนวทางของคุณดีกว่ามาก กรุณาเพิ่มเป็นคำตอบและฉันจะโหวตให้
dss539

15

ในฐานะที่เป็นคำตอบที่ยอมรับของ Goran และความคิดเห็นที่ยอดเยี่ยมของ Rene

  • เพิ่มการประกาศเนมสเปซ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

  • อ้างอิงบริบทข้อมูลเวลาออกแบบของคุณจากโค้ด
    <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" ...


1
ฉันอยากจะทำเครื่องหมายว่านี่เป็นคำตอบใหม่ แต่บางทีเราอาจดึงรายละเอียดที่เหลือได้
el2iot2

สิ่งนี้ต้องการการมองเห็นมากขึ้นหรือจำเป็นต้องดึงเข้ามาในคำตอบที่ยอมรับ เป็นทางออกที่ดีกว่ามาก
Lauraducky

ทำไมถึงดีกว่านี้ ตอนแรกฉันคิดว่าคำตอบที่ได้รับการยอมรับจะสร้างโมเดลจำลองโดยไม่จำเป็นในรันไทม์ด้วย แต่ฉันทดสอบแล้วและในความเป็นจริงไม่ได้ ทรัพยากรจะไม่ถูกสร้างขึ้นหากไม่ใช้
พอล

@ พอลเป็นเรื่องของการตั้งค่า แต่คำตอบนี้จะคงบริบทข้อมูลเวลาออกแบบทั้งหมดไว้ในการประกาศครั้งเดียวเทียบกับการมีสองจุด ทำให้การเปลี่ยนแปลงง่ายขึ้น
John Stritenberger

1
@JohnStritenberger ไม่ใช่แค่ความชอบ แต่คำตอบที่ยอมรับโดยไม่จำเป็นต้องโหลดทรัพยากรลงในหน่วยความจำตลอดเวลาไม่ใช่เฉพาะสำหรับนักออกแบบเท่านั้น
UuDdLrLrSs

4

Karl Shifflett อธิบายถึงแนวทางที่ควรทำงานได้ดีพอ ๆ กันสำหรับ VS2008 และ VS2010:

การดูข้อมูลเวลาออกแบบใน Visual Studio 2008 Cider Designer ใน WPF และ Silverlight Projects

Laurent Bugnion มีแนวทางที่คล้ายกันโดยเน้นที่ Expression Blend มันอาจจะทำงานสำหรับ VS2010 แต่ผมยังไม่ได้รับการยืนยันนี้เลย

การจำลองข้อมูลในโหมดออกแบบใน Microsoft Expression Blend


ขอบคุณที่แจ้งเรื่องนี้ให้ฉันทราบ ฉันชอบแนวคิด DesignAndRunTimeDataContext
el2iot2

1
Karl Shifflett มีบทความที่อัปเดตสำหรับ Visual Studio 2010: ตัวอย่างข้อมูลใน WPF และ Silverlight Designer
totorocat

1
ส่วนสำคัญของเนื้อหาลิงก์ควรได้รับการแก้ไขเป็นคำตอบโดยเฉพาะอย่างยิ่งเนื่องจากลิงก์แรกได้ตายไปแล้ว
Lauraducky

4

คุณสมบัติเวลาออกแบบใหม่ของ Visual Studio 2010 และ Expression Blend 4 อาจเป็นตัวเลือกสำหรับคุณ

วิธีการทำงานจะแสดงในBookLibraryโปรแกรมตัวอย่างของWPF Application Framework (WAF) โปรดดาวน์โหลดเวอร์ชัน. NET4


ขอบคุณสำหรับลิงค์ มีไฟล์โค้ดหรือโครงสร้างเฉพาะที่ฉันควรดูเพื่อดูแนวทางหรือไม่? (ภาพรวมคร่าวๆจะดีมาก)
el2iot2

ดูโครงการ BookLibrary.Presentation ในโปรเจ็กต์นี้คุณจะพบโฟลเดอร์ "DesignData" ซึ่ง UserControls ใช้ในโฟลเดอร์ "Views"
jbe

1
+1. เพิ่งได้ดูที่นี้ สำหรับใครก็ตามที่สนใจโมเดลมุมมองข้อมูลตัวอย่างจะประกาศใน XAML และอ้างอิงผ่าน d: DataContext = "{d: DesignData Source = .. / DesignData / SampleLendToViewModel.xaml}"
RichardOD

4

ฉันใช้แนวทางนี้ในการสร้างข้อมูลเวลาออกแบบด้วย. NET 4.5 และ Visual Studio 2013

ฉันมี ViewModel เพียงตัวเดียว โมเดลมุมมองมีคุณสมบัติIsInDesignModeที่บอกว่าโหมดการออกแบบแอ็คทีฟหรือไม่ (ดูคลาสViewModelBase) จากนั้นคุณสามารถตั้งค่าข้อมูลเวลาออกแบบของคุณ (เช่นการกรอกตัวควบคุมรายการ) ในตัวสร้างโมเดลมุมมอง

นอกจากนี้ฉันจะไม่โหลดข้อมูลจริงในตัวสร้างโมเดลมุมมองซึ่งอาจนำไปสู่ปัญหาที่รันไทม์ แต่การตั้งค่าข้อมูลสำหรับเวลาออกแบบไม่ควรมีปัญหา

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

ใช้ Visual Studio 2017 ฉันได้รับการพยายามที่จะทำตามทุกคำแนะนำและคำถามเช่นนี้และผมก็ยังคงเผชิญ<ItemsControl>ซึ่งก็ไม่ได้รันโค้ดที่ฉันมีอยู่ภายในสร้างของที่ซึ่งสืบทอดมาจากDesignFooViewModel FooViewModelฉันยืนยันว่าส่วน "ไม่ได้ดำเนินการ" ตามคู่มือ MSDN "ที่มีประโยชน์" นี้ (สปอยเลอร์: การMessageBoxดีบัก) แม้ว่าสิ่งนี้จะไม่เกี่ยวข้องโดยตรงกับคำถามเดิม แต่ฉันหวังว่ามันจะช่วยคนอื่นได้มาก

ปรากฎว่าฉันไม่ได้ทำอะไรผิด ปัญหาคือแอปพลิเคชันของฉันต้องสร้างขึ้นสำหรับ x64 เนื่องจากVisual Studio ยังอยู่ในปี 2018 ซึ่งเป็นกระบวนการ 32 บิตและดูเหมือนจะไม่สามารถหมุนกระบวนการโฮสต์ 64 บิตสำหรับส่วนนักออกแบบจึงไม่สามารถใช้คลาส x64 ของฉันได้ สิ่งที่แย่มากคือไม่มีข้อผิดพลาดใด ๆ ให้พบในบันทึกใด ๆ ที่ฉันคิดได้

ดังนั้นหากคุณสะดุดกับคำถามนี้เนื่องจากคุณเห็นข้อมูลปลอมในโมเดลมุมมองเวลาออกแบบของคุณ (ตัวอย่างเช่น: <TextBlock Text="{Binding Name}"/>ปรากฏขึ้นNameไม่ว่าคุณจะตั้งค่าคุณสมบัติเป็น) สาเหตุก็น่าจะเป็นบิลด์ x64 ของคุณ หากคุณไม่สามารถเปลี่ยนคอนฟิกูเรชันบิลด์ของคุณเป็น anycpu หรือ x86 ได้เนื่องจากการอ้างอิงให้พิจารณาสร้างโปรเจ็กต์ใหม่ซึ่งเป็น anycpu เต็มรูปแบบและไม่มีการอ้างอิง (หรือการอ้างอิงใด ๆ ) ดังนั้นคุณจึงแยกส่วนการเริ่มต้นส่วนใหญ่หรือทั้งหมดออก แต่ส่วนเริ่มต้นของโค้ดออกจากโครงการ "แอป WPF" ของคุณเป็นโครงการ "ไลบรารีคลาส C #"

สำหรับ codebase ฉันกำลังดำเนินการอยู่ฉันคิดว่าสิ่งนี้จะบังคับให้แยกความกังวลออกจากกันโดยมีค่าใช้จ่ายในการทำซ้ำรหัสซึ่งอาจเป็นสิ่งที่เป็นบวกสุทธิ


3

คล้ายกับคำตอบอันดับต้น ๆ แต่ในความคิดของฉันดีกว่า: คุณสามารถสร้างคุณสมบัติคงที่เพื่อส่งคืนอินสแตนซ์ของข้อมูลการออกแบบและอ้างอิงโดยตรงจาก XAML ดังนี้:

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

UserControl.Resourcesนี้หลีกเลี่ยงความจำเป็นในการใช้งาน คุณสมบัติคงที่ของคุณสามารถทำหน้าที่เป็นโรงงานเพื่อให้คุณสร้างชนิดข้อมูลที่ไม่สำคัญได้ตัวอย่างเช่นหากคุณไม่มี ctor เริ่มต้นคุณสามารถเรียกโรงงานหรือคอนเทนเนอร์ที่นี่เพื่อฉีดในการอ้างอิงที่เหมาะสม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.