Có những cách tiếp cận nào đối với dữ liệu thời gian thiết kế giả trong WPF?


97

Tôi đang làm việc mà không có sự pha trộn biểu thức và chỉ sử dụng trình chỉnh sửa XAML trong vs2010. Bên cạnh sự khôn ngoan của điều này, tôi ngày càng nhận thấy nhu cầu ràng buộc dữ liệu thời gian thiết kế. Đối với các trường hợp đơn giản, thuộc FallbackValuetính hoạt động rất tốt (Hộp văn bản và Khóa văn bản, v.v.). Nhưng đặc biệt khi xử lý ItemsControlvà những thứ tương tự, người ta thực sự cần dữ liệu mẫu hiển thị trong trình thiết kế để bạn có thể điều chỉnh và tinh chỉnh các điều khiển và mẫu dữ liệu mà không cần phải chạy tệp thực thi.

Tôi biết rằng điều đó ObjectDataProvidercho phép liên kết với một loại và do đó có thể cung cấp dữ liệu thời gian thiết kế để hiển thị trực quan, nhưng sau đó có một số sự xáo trộn để cho phép liên kết dữ liệu thời gian thực, mà không lãng phí tài nguyên bằng cách tải cả thời gian thiết kế, dữ liệu dummied và các ràng buộc thời gian chạy.

Thực sự điều tôi muốn là khả năng có, chẳng hạn như "John", "Paul", "George" và "Ringo" hiển thị trong trình thiết kế XAML dưới dạng các mục có thể tạo kiểu trong của tôi ItemsControl, nhưng có dữ liệu thực tế hiển thị khi ứng dụng chạy.

Tôi cũng biết rằng Blend cho phép một số thuộc tính ưa thích xác định dữ liệu ràng buộc thời gian thiết kế bị WPF bỏ qua một cách hiệu quả trong điều kiện thời gian chạy.

Vì vậy, câu hỏi của tôi là:

1. Làm cách nào để tận dụng các ràng buộc về thời gian thiết kế của các bộ sưu tập và dữ liệu không quan trọng trong trình thiết kế XAML của studio trực quan và sau đó hoán đổi các ràng buộc thời gian chạy một cách suôn sẻ?

2. Những người khác đã giải quyết vấn đề dữ liệu thời gian thiết kế so với thời gian chạy như thế nào? Trong trường hợp của tôi, tôi không thể dễ dàng sử dụng cùng một dữ liệu cho cả hai (như một người có thể với, chẳng hạn như truy vấn cơ sở dữ liệu).

3. Có phải các lựa chọn thay thế của họ cho hỗn hợp biểu thức mà tôi có thể sử dụng cho thiết kế XAML tích hợp dữ liệu không? (Tôi biết có một số lựa chọn thay thế, nhưng tôi đặc biệt muốn thứ gì đó mà tôi có thể sử dụng và xem dữ liệu mẫu bị ràng buộc, v.v.?)

Câu trả lời:


120

Sử dụng VS2010, bạn có thể sử dụng các thuộc tính Design-Time (hoạt động cho cả SL và WPF). Dù sao thì tôi cũng thường có một nguồn dữ liệu giả nên vấn đề chỉ là:

  • Thêm khai báo vùng tên

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  • Thêm bối cảnh dữ liệu giả vào tài nguyên cửa sổ / điều khiển

    <UserControl.Resources>
      <ViewModels:MockXViewModel x:Key="DesignViewModel"/>
    </UserControl.Resources>
    
  • Đặt bối cảnh dữ liệu thời gian thiết kế

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

Hoạt động đủ tốt.


2
Nếu bạn đang gặp vấn đề về sử dụng d:DataContextbạn có thể tìm thấy một số giúp đỡ trong vấn đề này: stackoverflow.com/questions/8303803/...
Martin Liversage

27
Ví dụ này sẽ không khiến một phiên bản MockXViewModel được tải vào tài nguyên của bạn cho một bản phát hành? Đây không phải là một mối quan tâm?
jpierson

12
FYI: Bạn cũng cần những điều sau đây, hoặc trình biên dịch VS2012 sẽ không biên dịch các tập tin XAML: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"
Orion Edwards

51
jpierson đúng. Tôi thích sử dụng hơn <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" .... Bằng cách này, mô hình chế độ xem giả sẽ chỉ được tạo trong trình thiết kế, không phải trong khi chạy ứng dụng của bạn. Hãy nhớ rằng cách tiếp cận này yêu cầu mô hình chế độ xem giả của bạn phải có một hàm tạo không tham số. Nhưng tương tự là trường hợp trong ví dụ được đưa ra ở trên trong câu trả lời.
René

2
@ René cách tiếp cận của bạn tốt hơn nhiều. Vui lòng thêm nó như là một câu trả lời và tôi sẽ bỏ phiếu cho nó
dss539

15

Như một hỗn hợp của câu trả lời được chấp nhận của Goran và nhận xét xuất sắc của Rene.

  • Thêm khai báo không gian tên. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

  • Tham khảo ngữ cảnh dữ liệu thời gian thiết kế của bạn từ mã.
    <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" ...


1
Tôi muốn đánh dấu đây là câu trả lời mới, nhưng có lẽ chúng ta có thể xem phần còn lại của chi tiết.
el2iot2

Điều này cần được hiển thị nhiều hơn, hoặc nó cần được đưa vào câu trả lời được chấp nhận. Đó là một giải pháp tốt hơn nhiều.
Lauraducky

Tại sao điều này tốt hơn? Lúc đầu, tôi nghĩ rằng câu trả lời được chấp nhận sẽ tạo ra các mô hình giả một cách không cần thiết trong thời gian chạy nhưng tôi đã kiểm tra điều đó và thực tế là không. Tài nguyên không được tạo ra nếu không được sử dụng.
Paul

@Paul Đây thực sự là một vấn đề ưu tiên, nhưng câu trả lời này giữ toàn bộ bối cảnh dữ liệu thời gian thiết kế trong một khai báo so với có nó ở hai vị trí. Thay đổi dễ dàng hơn
John Stritenberger

1
@JohnStritenberger Không chỉ sở thích của nó, câu trả lời được chấp nhận sẽ tải tài nguyên vào bộ nhớ mọi lúc một cách không cần thiết, không chỉ cho người thiết kế.
UuDdLrLrSs

4

Karl Shifflett mô tả một cách tiếp cận phải hoạt động tốt như nhau cho VS2008 và VS2010:

Xem dữ liệu thời gian thiết kế trong Visual Studio 2008 Cider Designer trong dự án WPF và Silverlight

Laurent Bugnion có cách tiếp cận tương tự tập trung vào Expression Blend. Nó có thể hoạt động cho VS2010, nhưng tôi chưa xác nhận điều này.

Mô phỏng dữ liệu trong chế độ thiết kế trong Microsoft Expression Blend


Cảm ơn vì đã mang đến sự chú ý của tôi. Tôi thích khái niệm DesignAndRunTimeDataContext.
el2iot2

1
Karl Shifflett có một bài báo cập nhật cho Visual Studio 2010: Mẫu Dữ liệu trong WPF và Silverlight Designer
totorocat

1
Ý chính của nội dung liên kết thực sự nên được chỉnh sửa thành câu trả lời, đặc biệt là vì liên kết đầu tiên hiện đã chết.
Lauraducky

4

Có thể các tính năng thời gian thiết kế mới của Visual Studio 2010 và Expression Blend 4 là một lựa chọn cho bạn.

Cách nó hoạt động được hiển thị trong ứng dụng mẫu BookLibrary của Khung ứng dụng WPF (WAF) . Vui lòng tải xuống phiên bản .NET4.


Cảm ơn các liên kết. Có tệp mã hoặc cấu trúc cụ thể nào mà tôi nên xem để xem cách tiếp cận không? (một cái nhìn tổng quan ngắn gọn sẽ rất tuyệt)
el2iot2

Hãy xem dự án BookLibrary.Presentation. Trong dự án này, bạn tìm thấy thư mục "DesignData" được UserControls sử dụng trong thư mục "Views".
jbe

1
+1. Chỉ cần có một cái nhìn vào này. Đối với bất cứ ai quan tâm đến mô hình xem dữ liệu mẫu được khai báo trong XAML và tham chiếu qua d: DataContext = "{d: DesignData Source = .. / DesignData / SampleLendToViewModel.xaml}"
RichardOD

4

Tôi sử dụng phương pháp này để tạo dữ liệu thời gian thiết kế với .NET 4.5 và Visual Studio 2013.

Tôi chỉ có một ViewModel. Mô hình khung nhìn có một thuộc tính IsInDesignModecho biết chế độ thiết kế có đang hoạt động hay không (xem lớp ViewModelBase). Sau đó, bạn có thể thiết lập dữ liệu thời gian thiết kế của mình (như điền vào một điều khiển mục) trong hàm tạo mô hình chế độ xem.

Bên cạnh đó, tôi sẽ không tải dữ liệu thực trong phương thức khởi tạo mô hình xem, điều này có thể dẫn đến sự cố trong thời gian chạy, nhưng việc thiết lập dữ liệu cho thời gian thiết kế sẽ không thành vấn đề.

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

Sử dụng Visual Studio 2017, tôi đã cố gắng làm theo tất cả các hướng dẫn và câu hỏi như thế này và tôi vẫn gặp phải lỗi <ItemsControl>đơn giản là không thực thi mã mà tôi có bên trong hàm tạo DesignFooViewModelkế thừa từ đó FooViewModel. Tôi đã xác nhận phần "không thực thi" theo hướng dẫn MSDN "tiện dụng" này (spoiler: MessageBoxgỡ lỗi). Mặc dù điều này không liên quan trực tiếp đến câu hỏi ban đầu, tôi hy vọng nó sẽ giúp người khác tiết kiệm được nhiều thời gian.

Hóa ra tôi không làm gì sai. Vấn đề là ứng dụng của tôi cần được xây dựng cho x64. Vì Visual Studio vẫn đang ở trong năm 2018, quy trình 32 bit và dường như không thể quay quy trình lưu trữ 64 bit cho phần thiết kế nên nó không thể sử dụng các lớp x64 của tôi. Điều thực sự tồi tệ là không có lỗi nào được tìm thấy trong bất kỳ nhật ký nào mà tôi có thể nghĩ ra.

Vì vậy, nếu bạn vấp phải câu hỏi này vì bạn đang thấy dữ liệu không có thật trong mô hình xem thời gian thiết kế của mình (ví dụ: <TextBlock Text="{Binding Name}"/>hiển thị Namebất kể bạn đặt thuộc tính) thì nguyên nhân có thể là do bản dựng x64 của bạn. Nếu bạn không thể thay đổi cấu hình xây dựng của mình thành anycpu hoặc x86 do phụ thuộc, hãy xem xét tạo một dự án mới hoàn toàn là anycpu và không có các phụ thuộc (hoặc bất kỳ phụ thuộc nào). Vì vậy, bạn sẽ tách hầu hết hoặc tất cả trừ các phần khởi tạo của mã khỏi dự án "Ứng dụng WPF" của bạn thành dự án "thư viện lớp C #".

Đối với cơ sở mã mà tôi đang nghiên cứu, tôi nghĩ rằng điều này sẽ buộc phải tách biệt lành mạnh các mối quan tâm với chi phí trùng lặp mã có lẽ là điều tích cực.


3

Tương tự như câu trả lời được xếp hạng cao nhất, nhưng tốt hơn theo quan điểm của tôi: Bạn có thể tạo một thuộc tính tĩnh để trả về một phiên bản của dữ liệu thiết kế và tham chiếu trực tiếp từ XAML như sau:

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

Điều này tránh được nhu cầu sử dụng UserControl.Resources. Thuộc tính tĩnh của bạn có thể hoạt động như một nhà máy cho phép bạn tạo các kiểu dữ liệu không tầm thường - ví dụ: nếu bạn không có ctor mặc định, bạn có thể gọi một nhà máy hoặc vùng chứa ở đây để đưa vào các phụ thuộc thích hợp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.