2009-02-25 31 views
22

tôi tự hỏi liệu có cách nào để sử dụng thuộc tính basedOn của kiểu wpf với dynamicresources không. ví dụ.Sử dụng thuộc tính StyleOn trên DynamicResources

<Style BasedOn="{DynamicResource somestyle}"> 
    <Setter Property="SomeProp" Value="SomeValue"/> 
</Style> 

ví dụ: ném một lỗi chỉ ra rằng việc sử dụng dynamicresources kết hợp với phong cách BasedOn là không thể. tôi tự hỏi làm thế nào ai đó có thể làm điều đó? cảm ơn

Trả lời

15

Tôi nghĩ lý do chính là các đối tượng bịt kín. Nếu bạn có phân cấp Kiểu:

 Style A 
    /  \ 
    Style A1 Style A2 

đây có thể không phải là một tình huống khó. Bạn tham khảo StyleA sử dụng tài nguyên động, vì vậy bất cứ khi nào tài nguyên đó thay đổi, Style A1Style A2 sẽ thay đổi thuộc tính BasedOn của chúng. Tuy nhiên, khi một Style đang được sử dụng trong ứng dụng của bạn, nó sẽ trở thành một đối tượng kín. Style A trở thành không thay đổi.

Một workaround bạn có thể sử dụng là:

  1. Style A cần phải thay đổi.
  2. Tạo đối tượng Kiểu mới sẽ là tài nguyên mới Style A.
  3. Tạo phiên bản mới Style A1Style A2. Bạn cần phải viết một thủ tục sao chép tạo bản sao của tất cả các Setters, Resources, v.v ... Đặt BasedOn thành phiên bản mới Style A.
  4. Cập nhật bộ sưu tập tài nguyên để ba kiểu mới có trong đó.

{DynamicResource StyleA1}{DynamicResource StyleA2} bây giờ sẽ nhận thực tế là các tài nguyên đó thay đổi (từ bước 4) và tự động cập nhật bất kỳ tham chiếu nào.

Lưu ý rằng đây là một tình huống rất đơn giản. Hệ thống phân cấp theo phong cách thế giới thực có thể phức tạp hơn, đặc biệt nếu chúng được trải rộng trên nhiều tệp và đến từ các từ điển đã hợp nhất.

Hy vọng tôi đã hiểu sự cố của bạn và giúp đỡ.

+4

Làm thế nào về trường hợp này - Một nhóm (Ux) khác tạo ra kiểu cơ sở ... nhà phát triển muốn đặt một vài thuộc tính ngoài kiểu cơ sở.Lý tưởng nhất đây là một kịch bản mà DevStyle BasedOn "DynamicResource UxStyle" sẽ giúp .. Nếu điều này là không thể, các lựa chọn thay thế để hợp nhất 2 phong cách trước khi áp dụng nó vào một điều khiển là gì? – Gishu

12

Tôi đã phát hiện ra rằng kể từ khi bạn không thể sử dụng BasedOn trên DynamicResource, bạn có thể "chuyển đổi" các DynamicResource để StaticResource bằng cách sáp nhập các ResourceDictionary giữ "cha mẹ" của bạn nguồn lực để Window hiện tại của bạn/UserControl/bất cứ điều gì. Bằng cách này, bạn có thể tham khảo đối tượng tài nguyên (ví dụ: Style) sử dụng StaticResource. Bằng cách này, bạn có thể sử dụng Datatriggers trên DynamicResource (thông qua chuyển đổi).

Ví dụ:

<Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/MyProject.Styles;component/ButtonStyles.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
     [*Your other resources can be put here*] 
    </ResourceDictionary> 
</Window.Resources> 

... 

<Button Command="{Binding MyCommandInViewModel, RelativeSource={RelativeSource AncestorType=Window}}"> 
    <Button.Style> 
     <Style BasedOn="{StaticResource StyleFromButtonStyles}" TargetType="Button"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding SomeBool}" Value="True"> 
        <Setter Property="Button.Content" Value="{StaticResource SomeImage}"/> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SomeBool}" Value="False"> 
        <Setter Property="Button.Content" Value="{StaticResource SomeOtherImage}"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Button.Style> 
</Button> 

Do đó Datatriggers được áp dụng cho một nút theo kiểu trong một nhập khẩu ResourceDictionary.

Hy vọng điều này sẽ hữu ích!

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