2011-01-26 39 views
34

Tôi đã triển khai skinning trong ứng dụng của mình. Ứng dụng tải từ điển tài nguyên Brushes.xaml của nó sử dụng các màu sắc nằm trong một từ điển tài nguyên cụ thể cho da. Vì vậy, chỉ có một Color.xaml được nạp tùy thuộc vào da đã chọn.Skinning: Sử dụng màu như StaticResource cho một màu khác

Skin Cụ thể Color.xaml

<Color x:Key="TextBoxBackgroundColor">#C4AF8D</Color> 
    <Color x:Key="TextBoxForegroundColor">#6B4E2C</Color> 
    <Color x:Key="ToolBarButtonForegroundColor">#6B4E2C</Color> 

Brushes.xaml:

<SolidColorBrush 
     x:Key="TextBoxBackground" 
     Color="{DynamicResource TextBoxBackgroundColor}" /> 
    <SolidColorBrush 
     x:Key="TextBoxForeground" 
     Color="{DynamicResource TextBoxForegroundColor}" /> 

Như bạn có thể thấy, nhiều màu sắc (TextBoxForegroundColor và ToolBarButtonForegroundColor) đều giống nhau. Tôi muốn phá vỡ điều đó vì nó ngày càng trở nên khó hiểu hơn, đặc biệt là vì các màu đã sử dụng không thể nhận biết được bởi giá trị hex của chúng. Bạn có thể tư vấn ngay bây giờ để hợp nhất cả hai màu vào một nhưng tôi có da, nơi TextBoxForegroundColor là khác nhau từ ToolBarButtonForegroundColor.

Những gì tôi muốn làm là một cái gì đó như thế này:

<Color x:Key="DarkBrown">#C4AF8D</Color> 

<Color x:Key="TextBoxBackgroundColor" Color={StaticResource DarkBrown} /> 
<Color x:Key="ToolBarButtonForegroundColor" Color={StaticResource DarkBrown} /> 

Đây có phải là ở tất cả các khả năng trong XAML? Tôi không tìm được cách nào.

Trả lời

34

Điều này?

<Color x:Key="DarkBrown">#C4AF8D</Color> 

<DynamicResource x:Key="TextBoxBackgroundColor" ResourceKey="DarkBrown"/> 
<DynamicResource x:Key="ToolBarButtonForegroundColor" ResourceKey="DarkBrown"/> 

(trình bằng cách này)

+3

Điều đó trông rất thú vị nhưng tôi không làm cho nó hoạt động. Tôi đã cố gắng đặt nhưng điều này kích hoạt thông báo lỗi "Một đối tượng thuộc loại" System.Windows.DynamicResourceExtension "không thể được áp dụng cho thuộc tính mong đợi loại "System.Windows.Media.Color". Tôi có làm gì sai không? – Amenti

+0

Bạn cần tham khảo nó như là một StaticResource ('Color =" {StaticResource TextBoxBackgroundColor} "') bởi vì nó thực chất là một tài nguyên tĩnh mặc dù –

+1

Tôi đã thử và bây giờ nó biên dịch và hoạt động.Nhưng tôi vẫn nhận được các lỗi trong IDE (Visual Studio 2010 Express) nhưng bây giờ liên quan đến System.Windows.StaticResourceExtension.Đây là vấn đề vì nó có hiệu quả làm tê liệt thiết kế -Thời gian sử dụng của Gui-Editor trong IDE.Nhưng vẫn tuyệt vời mà nó có thể làm việc theo cách đó.Bạn có bất cứ ý tưởng tại sao điều này xảy ra? Đây có phải là lỗi trong VS hoặc tôi đang làm điều gì đó sai? – Amenti

2

Phần cuối cùng không thể thực hiện được vì Màu không có thuộc tính Màu.

Màu sắc có thuộc tính R, G, B và A. Vì vậy, bạn có thể tạo bốn byte làm tài nguyên:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib"> 
    <sys:Byte x:Key="r">#23</sys:Byte> 
    <sys:Byte x:Key="g">#45</sys:Byte> 
    <sys:Byte x:Key="b">#67</sys:Byte> 
    <sys:Byte x:Key="a">#FF</sys:Byte> 

    <Color x:Key="c1" R="{StaticResource r}" 
     G="{StaticResource g}" 
     B="{StaticResource b}" 
     A="{StaticResource a}"/> 

    <Color x:Key="c2" R="{StaticResource r}" 
     G="{StaticResource g}" 
     B="{StaticResource b}" 
     A="{StaticResource a}"/> 

</ResourceDictionary> 

Vẫn không phải những gì bạn có thể thích nhưng nó sẽ hoạt động.

+0

Cảm ơn. Vâng, điều này sẽ làm việc nhưng tôi nghĩ rằng việc thay đổi màu sắc trở nên tẻ nhạt theo cách này, nếu bạn phải sao chép và dán 4 chuỗi thay vì 1 từ chương trình đồ họa. – Amenti

+0

Vâng, tôi hoàn toàn đồng ý. –

+0

+1 cho câu trả lời đúng :-) – kux

7

Tại sao bạn không chỉ làm cho Brushes.xaml dành riêng cho da? Sau đó, bạn sẽ có điều này:

<Color x:Key="DarkBrown">#C4AF8D</Color> 

<SolidColorBrush x:Key="TextBoxBackgroundBrush" Color={StaticResource DarkBrown} /> 
<SolidColorBrush x:Key="ToolBarButtonForegroundBrush" Color={StaticResource DarkBrown} /> 

Một điểm ủng hộ việc làm cho bàn chải da cụ thể là có những tình huống mà bạn sẽ muốn làm cho ToolBarButtonForegroundBrush một bàn chải màu rắn trong một da và một bàn chải gradient trong khác.

+0

Cảm ơn. Da của tôi thường nhưng không phải lúc nào cũng sử dụng cùng màu cho cùng một cọ vẽ. Vì vậy, tôi sẽ phải sao chép Brushes.xaml của tôi cho mỗi làn da và sau đó điều chỉnh các tài nguyên màu trong đó. Tôi không chắc liệu điều này có còn hiệu quả hơn không. – Amenti

+0

Có, nhưng phương pháp này sẽ cung cấp cho bạn sự linh hoạt nhất và có thể có lợi hơn trong một thời gian dài. –

6

câu trả lời H.B. là rất thú vị và tôi đã chơi đùa với nó khá một chút kể từ khi tôi muốn làm chính xác những gì câu hỏi này là yêu cầu để làm.

Điều tôi nhận thấy là việc sử dụng DynamicResource không hoạt động đối với WPF 3.5. Đó là, nó ném một ngoại lệ vào thời gian chạy (một trong những Amenti nói về). Tuy nhiên, nếu bạn tạo màu sắc tham chiếu màu bạn muốn chia sẻ ... một StaticResource, nó hoạt động trên cả WPF 3.5 và WPF 4.0.

Đó là, XAML này làm việc cho cả hai WPF 3.5 và WPF 4.0:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="ColorsReferencingColors.MainWindow" 
    x:Name="Window" 
    Title="MainWindow" 
    Width="640" 
    Height="480" 
> 
    <Window.Resources> 
     <Color x:Key="DarkBlue">DarkBlue</Color> 
     <StaticResource x:Key="EllipseBackgroundColor" ResourceKey="DarkBlue"/> 
     <SolidColorBrush 
      x:Key="ellipseFillBrush" 
      Color="{DynamicResource EllipseBackgroundColor}" 
     /> 
    </Window.Resources> 
    <Grid> 
     <StackPanel Margin="25"> 
      <Ellipse 
       Width="200" 
       Height="200" 
       Fill="{DynamicResource ellipseFillBrush}" 
      /> 
     </StackPanel> 
    </Grid> 
</Window> 

Một điều mà gấu nhắc đến (một lần nữa) là phương pháp này tàn phá với các nhà thiết kế ngoài kia (tức là Visual Studio Các nhà thiết kế năm 2008 và 2010, nhà thiết kế Blend 3 và 4). Tôi suy đoán rằng đây cũng là lý do tại sao Kaxaml 1.7 không thích xaml của H.B. (nếu bạn đang theo dõi luồng bình luận trên câu trả lời của H.B.).

Nhưng trong khi nó phá vỡ các nhà thiết kế cho một trường hợp thử nghiệm đơn giản, nó dường như không phá vỡ bề mặt thiết kế cho các ứng dụng quy mô lớn tôi làm việc trong công việc ngày của tôi. Đồng bằng kỳ lạ! Nói cách khác, nếu bạn quan tâm về mọi thứ vẫn còn làm việc trong nhà thiết kế, hãy thử phương pháp này ra anyway ... nhà thiết kế của bạn vẫn có thể làm việc!

+0

Cảm ơn mô tả chi tiết của bạn (+1). Thật không may trong trường hợp của tôi nó phá vỡ các nhà thiết kế. Tôi vẫn còn sử dụng VS Express mặc dù, có thể đó là một vấn đề trong chính nó (tôi không tin nó mặc dù). – Amenti

+0

Bản cập nhật. Tôi rất buồn, nhưng mẹo này ... trong khi nó hoạt động cho ứng dụng chính của chúng tôi, nó không hoạt động cho một vài ứng dụng tiện ích chia sẻ các tệp da của chúng tôi (bao gồm cả xaml ở trên). Vì vậy, thật không may, tôi sẽ phải quay trở lại. – cplotts

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