2009-08-04 29 views
41

Tôi có thư viện, CommonLibraryWpfThemes, với một số tệp XAML từ điển tài nguyên trong đó. Các tệp My Themes/Generic.xml chứa một khai báo ResourceDictionary.MergedDictionaries kết hợp tất cả các tệp khác với nhau.Sự cố khi tham chiếu một Từ điển tài nguyên có chứa từ điển được hợp nhất

Generic.xaml

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary 
      Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/BrushDictionary.xaml" /> 
     <ResourceDictionary 
      Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/TextBlockDictionary.xaml" /> 
     <ResourceDictionary 
      Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/LabelDictionary.xaml" /> 
     <ResourceDictionary 
      Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/ButtonDictionary.xaml" /> 
     <ResourceDictionary 
      Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 
</ResourceDictionary> 

Trong dự án ứng dụng của tôi, tôi có một tham chiếu đến CommonLibraryWpfThemes, và tôi tham khảo một cách rõ ràng Generic.xml trong file App.xaml tôi.

App.xaml - KHÔNG

<Application 
    x:Class="MyApp.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Application.Resources> 
     <ResourceDictionary 
      Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" /> 
    </Application.Resources> 
</Application> 

này không hoạt động. Tôi nhận được lỗi sau khi tôi chạy ứng dụng của tôi:

System.Windows.Markup.XamlParseException occurred 
    Message="Cannot find resource named '{_fadedOrangeBrush}'. Resource names are case sensitive. Error at object 'System.Windows.Setter' in markup file 'CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml' Line 18 Position 13." 
    Source="PresentationFramework" 
    LineNumber=18 
    LinePosition=13 

Nếu tôi đặt nội dung của Generic.xaml vào App.xaml trực tiếp, mọi thứ hoạt động tốt:

App.xaml - thành công

<Application 
    x:Class="MyApp.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary 
        Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/BrushDictionary.xaml" /> 
       <ResourceDictionary 
        Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/TextBlockDictionary.xaml" /> 
       <ResourceDictionary 
        Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/LabelDictionary.xaml" /> 
       <ResourceDictionary 
        Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/ButtonDictionary.xaml" /> 
       <ResourceDictionary 
        Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

Có thể tôi sẽ nói về điều này một cách sai. Mục tiêu của tôi là giúp dễ dàng tham khảo tất cả tài nguyên chủ đề của tôi từ nhiều ứng dụng mà không phải liệt kê tất cả các tệp riêng lẻ. Có cách nào được khuyến nghị để làm điều này không? (Lưu ý: Tôi không cố chuyển đổi giữa nhiều chủ đề - tôi chỉ có một chủ đề.)

Là phần thưởng, sẽ rất tuyệt nếu ai đó có thể cho tôi biết cách tham chiếu tài nguyên trong thư viện bên ngoài mà không vi phạm thiết kế trong Visual Studio.

Cảm ơn.

EDIT:

tôi đã cố gắng gói các ResourceDictionary trong một phần tử ResourceDictionary.MergedDictionary, nhưng điều đó cũng không làm việc (tôi nhận được lỗi tương tự):

<Application 
    x:Class="MyApp.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary 
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 
+1

Tôi sẽ bắt đầu một khoản tiền thưởng nhỏ tại đây. Kết hợp một vài RessourceDictionaries vào một Theme (và chỉ tải nó trong App.xaml) có vẻ là một kịch bản đủ phổ biến ... – Jens

Trả lời

4

Bạn không nên có để tham khảo generic.xaml ở tất cả, nó có hỗ trợ tích hợp sẵn. Tuy nhiên, điều này có nghĩa là nó cung cấp kiểu dáng mặc định, mà bạn không đặt rõ ràng. Các mẫu/mẫu được đặt rõ ràng cần phải đạt được từ các từ điển được tham chiếu rõ ràng.

(EDIT cho rõ ràng)

Một ngoại lệ là các App.xaml, nơi các nguồn lực được xác định trở thành thể truy cập bằng toàn bộ ứng dụng, mà không cần phải tham khảo bất kỳ từ điển tài nguyên cụ thể. Bản thân tài nguyên, sẽ phải có thể truy cập theo tên.

Lý do tại sao điều này không

<Application.Resources> 
    <ResourceDictionary 
     Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" /> 
</Application.Resources> 

là, tôi nghĩ rằng, bởi vì bạn không bọc nó trong một wrapper MergedDictionary, thêm nó vào từ điển sáp nhập. Việc thêm trực tiếp vào tài nguyên chỉ hoạt động cho các tài nguyên bạn khai báo cục bộ, ví dụ: các phong cách, vv.Tuy nhiên, như tôi đã nói trước đây, bạn không cần phải hợp nhất generic.xaml ở bất cứ nơi nào, có thể bạn chỉ nên bàn chải refactor và các tài nguyên khác được sử dụng bên ngoài phong cách, và chỉ hợp nhất các tài nguyên đó trong app.xaml. Cũng cần lưu ý rằng các kiểu không phải nằm trong generic.xaml để có hành vi "kiểu mặc định" - nếu một kiểu có khóa bằng loại phần tử có thể truy cập được (toàn cục hoặc trong tài nguyên cục bộ), sau đó nó sẽ sử dụng kiểu như một kiểu mặc định. Các generic.xaml chỉ là một tiện lợi.

Kiểm tra câu trả lời this.

Đối với các bàn chải tùy chỉnh khác, v.v., bạn cần phải tham khảo một cách rõ ràng các tài nguyên đó.

Bạn cũng nên kiểm tra nội dung của số WindowDictionary.xaml, lỗi này có mùi nhất định về nó.

+0

Vì vậy, tôi nghĩ rằng bạn đang nói rằng tham chiếu ResourceDictionaries trực tiếp trong App.xaml là cần thiết và cách duy nhất nó sẽ công việc. I E., không có cách nào tôi có thể "hợp nhất" tất cả các từ điển của tôi và chỉ tham chiếu thực thể được hợp nhất trước từ App.xaml. Không thuận tiện, nhưng nếu đó là cách nó hoạt động, nó không phải là kết thúc của thế giới. Cho đến nay, tôi * luôn luôn * đặt thuộc tính Styles của tôi một cách rõ ràng bằng cách sử dụng '{StaticResource MyResourceName}', vì vậy tôi đoán tôi sẽ phải cấu trúc lại rất nhiều thứ để tận dụng hành vi mặc định mà Generic.xaml cho phép. Tôi có đúng không? – devuxer

+0

Khi bạn hợp nhất các từ điển với app.xaml, bạn tạo các tài nguyên "toàn cục", có thể truy cập được bằng toàn bộ ứng dụng (như tên của tiểu bang). Tài nguyên trong app.xaml không cần phải được tham chiếu qua tên từ điển, chỉ thông qua khóa tài nguyên cụ thể, có thể tôi chưa rõ về điều đó, tôi sẽ làm rõ câu trả lời. Tôi thường tạo các từ điển đã hợp nhất được nhóm lại cho các phần khác nhau của ứng dụng và tham khảo từ điển đó trong xaml theo yêu cầu. –

+0

Cảm ơn bạn đã làm rõ câu trả lời của bạn, nhưng hoặc là tôi hiểu sai ý nghĩa của bạn bằng cách "bọc nó trong một trình bao bọc' MergedDictionary' "hoặc nó không hoạt động. Tôi đặt một bản chỉnh sửa ở cuối câu hỏi của tôi với một mẫu mã. – devuxer

12

Kiểm tra xây dựng của bạn trong App.xaml.cs gọi InitializeComponent() - đây là những gì kết hợp các từ điển tài nguyên ...

+2

Điều này rất hữu ích đối với tôi. Tôi đã cố gắng tìm ra lý do tại sao Trang của tôi (được lưu trữ trong Khung) không nhận được Các tài nguyên được định nghĩa trong App.xaml của tôi Nó chỉ ra rằng các nhà xây dựng đã không gọi InitializeComponent Cảm ơn Chris !!!! – NathanAW

-1

Giải pháp của tôi là here, nhấp vào đối phó.

+1

Bình chọn cho: Liên kết không có văn bản liên kết; – trapicki

65

Đã trả lời câu hỏi tương tự ở đây trước đó, hãy xem Adding a Merged Dictionary to a Merged Dictionary câu hỏi.

Đây là một lỗi tối ưu hóa, xem Microsoft Connect/DefaultStyleKey style not found in inner MergedDictionaries:

Mở sự sáng tạo của mọi đối tượng trong XAML, nếu một phong cách mặc định là hiện (tức là phong cách w/a chính của Type) mà phong cách nên được áp dụng. Như bạn có thể hãy tưởng tượng có một số hiệu suất tối ưu hóa để thực hiện điều đó (ngụ ý) tra cứu trọng lượng nhẹ nhất có thể. Một trong số đó là chúng tôi không nhìn vào bên trong Từ điển tài nguyên trừ khi chúng là được gắn cờ là "chứa mặc định Kiểu". Có lỗi: nếu tất cả các kiểu mặc định của bạn được lồng trong từ điển được hợp nhất sâu (hoặc sâu hơn) từ điển trên cùng không bị gắn cờ để tìm kiếm bỏ qua nó. Công việc xung quanh là đặt một kiểu mặc định là vào một thứ gì đó, trong từ điển gốc .

Vì vậy, thêm kiểu giả vào từ điển gốc sẽ sửa lỗi này. Ví dụ

<Application x:Class="MyApp.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary 
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" /> 
       </ResourceDictionary.MergedDictionaries> 
      <!-- Dummy Style, anything you won't use goes --> 
      <Style TargetType="{x:Type Rectangle}" /> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 
+0

Lỗi này dường như chỉ xuất hiện trong các phiên bản cũ hơn của .NET 4: 4.0.30319.1008. Tôi đã thấy điều này trên XP và một số cài đặt Windows 7 chưa được cập nhật. –

0

Tôi đã gặp lỗi này trong các bài kiểm tra đơn vị của mình và câu trả lời của Chris từ trên đã cho tôi manh mối tôi cần. Về cơ bản phương pháp thử nghiệm đầu tiên của tôi, tôi đặt:

 MyApplication.App app = new MyApplication.App(); 
     app.InitializeComponent(); 

Và đột nhiên nó có thể tìm mẫu của tôi cho các trang của tôi. Lưu ý: điều này có nghĩa là bạn phải kiểm tra xem liệu một phiên bản ứng dụng của bạn đã tồn tại chưa nếu bạn đang thử nghiệm đơn vị App.cs của mình.

Các vấn đề liên quan