2013-04-24 24 views
7

Tôi hơi bối rối với các chủ đề wpf. Tôi muốn có các màn hình wpf trông giống nhau trên Vista, Windows 7 và Windows 8. Vì vậy, tôi đã theo kiểu các thành phần cho phù hợp và họ không đặt ra vấn đề ngoại trừ khi chạy trên Windows 8. Ví dụ tôi có một combobox và tôi thay đổi nền mặc định của nó trong xaml như thế này.Nền hộp tổ hợp không được áp dụng trong các cửa sổ 8

<Style TargetType="{x:Type ComboBox}" > 
    <Setter Property="FontStyle" Value="Normal"/> 
    <Setter Property="Height" Value="24" /> 
    <Setter Property="Background" Value="{StaticResource GradientButtonBackgroundBrush}"/> 
</Style> 

Thuộc tính combobox Bối cảnh không có tác dụng trong windows 8 và tất cả tôi nhận được là một hình chữ nhật phẳng với một mũi tên ở bên phải (cửa sổ mặc định 8 combobox, được chứ không phải được thiết kế kém!).

Vì vậy, câu hỏi của tôi là làm thế nào để tôi nhận được combobox trông giống nhau trên tất cả các phiên bản của cửa sổ. Tôi đã thử thêm cửa sổ Aero chủ đề trong App.xaml của tôi như dưới đây, nhưng nó không có hiệu lực trên màn hình combobox. Dưới đây là cách tôi thêm chủ đề Aero

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/PresentationFramework.Aero;component/themes/aero.normalcolor.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 

Ngoài ra còn có một nghi ngờ khác về chủ đề. Tôi đang xây dựng các ứng dụng wpf trên một cửa sổ 7 máy, mà theo mặc định (tôi tin) có Aero Theme thiết lập. Vì vậy, tất cả các phong cách của tôi dựa trên chủ đề Aero khi được xem trên máy tính Windows 7. Điều gì sẽ xảy ra nếu tôi chạy ứng dụng trên XP. Sau đó, tôi cần phải thêm một mục nhập cho từ điển tài nguyên (chủ đề Aero) trong App.xaml như được liệt kê trong mã ở trên không?

Tôi biết câu hỏi của mình hơi mơ hồ, nhưng hãy tin tôi, tôi thực sự nhầm lẫn với các chủ đề mặc định của wpf trên các phiên bản Windows khác nhau.

EDIT: Tôi vẫn không thể tạo combobox theo phong cách theo nhu cầu của mình. Hộp tổ hợp vẫn xuất hiện như một hình chữ nhật màu xám.

Đây là những gì tôi đã làm. Tôi đã tải xuống Aero.NormalColor.xaml từ trang web của microsoft và được đưa vào thư mục chủ đề của ứng dụng. Sau đó, tôi đã thêm thông tin sau vào trong App.xaml

<ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/Themes/Aero.NormalColor.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 

Sau đó, tôi đã biên dịch ứng dụng và triển khai trên Windows 8. Vẫn như một combobox như được hiển thị trước đó. Lưu ý rằng tất cả các yếu tố khác được tạo kiểu theo đúng chủ đề. Tôi đã làm tương tự với Luna.Metallic.xaml và mọi phần tử được tạo kiểu ngoại trừ ComboBox.

Tôi tin rằng khi tôi tải một chủ đề cụ thể, xác định kiểu với ControlTemplate, thì nó phải được chọn bởi wpf. Tôi bối rối là tại sao chỉ có ComboBox ngay cả sau khi cho nó một Aero (hoặc Luna) Mẫu kiểm soát không thay đổi sự xuất hiện của nó. Ý tưởng nào?

EDIT-2 Screen shot xuất hiện combobox trên Windows 8 enter image description here

+0

Tôi đã cập nhật câu trả lời cho chỉnh sửa của mình. Vui lòng thêm nhận xét trong các câu trả lời có liên quan hoặc câu hỏi của bạn. Nó không phải là rất dễ dàng để theo dõi khi bạn đưa ra nhận xét về câu trả lời mà không liên quan đến những gì bạn nêu rõ – Viv

Trả lời

2

Vâng khu vực có thể click ComboBox thực sự là một ToggleButton

và nếu bạn nhìn vào Style cho rằng ToggleButton trong Windows- 8, bạn thấy một cái gì đó như:

<ControlTemplate TargetType="{x:Type ToggleButton}"> 
    <Border x:Name="templateRoot" 
      Background="{StaticResource ComboBox.Static.Background}" 
      BorderBrush="{StaticResource ComboBox.Static.Border}" 
      BorderThickness="{TemplateBinding BorderThickness}" 
      SnapsToDevicePixels="true"> 
... 

Như bạn có thể thấy từ trên, Background được sử dụng không phải là {TemplateBinding Background} nhưng {StaticResource ComboBox.Static.Background}.Do đó tại sao bạn thấy không có tác dụng khi bạn thiết lập Background sở hữu trong Windows-8 cho rằng ComboBox

Nếu bạn đang tìm kiếm để thực hiện một Style trên các phiên bản hệ điều hành khác nhau (Mà không cần phải quay lại và liên tục kiểm tra nếu các phiên bản mới hơi say lên trên của bạn -rides), quy tắc đơn giản là tự mình Tự tạo.

Tạo Style và đặt nó sẽ được áp dụng bởi TargetType và không có Key để được áp dụng tự động. Bằng cách đó trong bất kỳ hệ điều hành nào là Style của bạn được sử dụng và không phải là cơ sở mặc định.

Điều này đảm bảo mã của bạn chạy như bạn mong đợi trên mọi hệ điều hành. Căn cứ Phong cách của bạn trên hệ điều hành mặc định của bất kỳ hệ điều hành nào và tinh chỉnh nó cho nội dung trái tim của bạn.

phụ lưu ý:

Từ một POV khả năng sử dụng cho người sử dụng Windows-7 ComboBox trong một ứng dụng chạy trên Windows 8 không phải là rất thoải mái (trừ trường hợp toàn bộ ứng dụng của bạn trông giống như một Windows 7 ứng dụng thậm chí còn tồi tệ hơn). Bạn mong đợi người dùng quen với Phong cách của ứng dụng và quên những gì anh ấy sử dụng từ mọi ứng dụng khác mà anh ấy sử dụng trong Hệ điều hành của mình sử dụng Kiểu mặc định dựa trên OS. Nếu bạn có lý do cụ thể để làm như vậy, hãy tiếp tục nhưng hãy xem xét các tác động.

Chỉ cần ví dụ bạn đã nêu kiểu Windows-8 là thứ mà bạn không phải là người hâm mộ, tôi cũng ngược lại. Tôi thực sự thích cái nhìn sạch sẽ và đơn giản của Windows 8. Không gây phiền nhiễu cho UserExperience với độ dốc nhấp nháy và những thứ làm bạn thất vọng với nội dung mà bạn đặt trước mặt họ. Đây là một cuộc tranh cãi cứ mãi mãi. Chỉ cần được cảnh báo abt những gì người dùng cuối mong đợi và suy nghĩ hơn là chỉ những gì bạn nghĩ là tốt trong khi viết chương trình của bạn.

Cập nhật:

Trước hết nhận xét về câu trả lời liên quan xin vui lòng. Câu trả lời của bạn và cập nhật nhận xét của bạn không có liên quan.

Ok và đối với chỉnh sửa câu hỏi của bạn, những gì bạn đã thử đã không hoạt động trong windows-8 vì PresentationFramework.Aero.dll không tồn tại trong Windows-8, đó là những gì giữ Aero.NormalColor.xaml. Trong Windows-8 các tùy chọn của bạn là PresentationFramework.Aero2.dll là mặc định và PresentationFramework.AeroLite.dll mà tôi nghĩ là được sử dụng bởi Windows Server 2012 (Không chắc chắn)

Cố gắng biên dịch chương trình của bạn trên Windows-8 và bạn sẽ thấy nó thậm chí không muốn biên dịch.

Bạn sẽ phải thêm rõ ràng tham chiếu đến PresentationFramework.Aero và cũng PresentationUI (mà tôi nghĩ là một phần của .net3) cho dự án của bạn.

Sau đó, bạn sẽ phải chỉnh sửa Aero.NormalColor.xaml của bạn để một cái gì đó như:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
        xmlns:ui="clr-namespace:System.Windows.Documents;assembly=PresentationUI"> 
... 

^^ chúng tôi một cách rõ ràng nêu rõ lắp ráp cho Aero Theme. Tôi không sử dụng Windows-7 vì vậy không chắc chắn nếu đó là tất cả những gì cần thiết. nhưng bạn có thể thử.

Cố gắng để biên dịch mã của bạn trong Windows 8 để chắc chắn rằng nó sẽ hoạt động tốt trên Windows-8

+0

Tôi đã làm theo các bước được đề xuất bởi bạn nhưng combobox vẫn xuất hiện trong màu xám. Vui lòng xem EDIT-2 của tôi về câu hỏi gốc cho ảnh chụp màn hình. Có lẽ điều đó sẽ gợi ý về chủ đề XAML đang được chọn. Biên dịch trên Windows 8 máy sẽ mất một thời gian như tôi không có Visual Studio 2010 được cài đặt trên máy đó. – Jatin

0

Trong Response to @Viv

@Viv, tôi cảm thấy rằng câu trả lời của bạn là rất rõ ràng, nhưng bằng cách nào đó quan điểm của bạn/gợi ý không digestable với tôi và tôi sẽ đề cập đến một thời gian ngắn tại sao

gợi ý của bạn

Nếu bạn muốn mang một Style trên các phiên bản hệ điều hành khác nhau (không cần phải quay lại và tiếp tục kiểm tra xem các phiên bản mới có làm say quá mức), quy tắc đơn giản là tự tạo nó.

Có vẻ như không thể thực hiện được. Ý tưởng rất chủ đề là tạo ra cái nhìn nhất quán cho tất cả các yếu tố trong ứng dụng và trên tất cả các nền tảng. Vì vậy, nếu tôi sử dụng một chủ đề cụ thể do khung công tác cung cấp, bất kể điều gì, tôi sẽ có thể đạt được mức độ nhất quán thỏa đáng, ít nhất là trên các nền tảng chính hiện tại. Trên hết, không phải ai cũng có chuyên môn để tạo ra tất cả các kiểu và mẫu từ đầu. Khái niệm về chủ đề nên là,

"Nhà cung cấp khung cung cấp chủ đề sẽ hoạt động tốt cho các tình huống bình thường và nếu có ai muốn đưa ra chủ đề, bạn có thể làm như vậy".

Thay vì ở đây khái niệm có vẻ như

"Các nhà cung cấp khuôn khổ đang cung cấp chủ đề và nó không được guranted rằng nó sẽ phù hợp và làm việc mà không vi phạm. Vì vậy, lúc nào cũng tung ra chủ đề của bạn"

của bạn báo giá

Như bạn có thể thấy từ trên, nền được sử dụng không phải là {TemplateBinding Background} nhưng {StaticResource ComboBox.Static.Background}. Do đó, tại sao bạn thấy không có hiệu lực khi bạn đặt thuộc tính Nền trong Windows-8 cho rằng ComboBox

Tôi không biết ý tưởng của nó là tạo mẫu theo cách nào! Phải ra khỏi tâm trí của mình hoặc tôi quá câm để hiểu được những lợi thế. Chỉ cần tưởng tượng rằng tôi đang sử dụng một số chủ đề màu Màu xanh trong ứng dụng của tôi và ngày mai, trên Windows 9, ai đó xác định một số Đỏ{StaticResource ComboBox.Static.Background}. Vì vậy, hãy đoán xem, tôi có màn hình cửa sổ ưa thích ngay bây giờ với tất cả các yếu tố của tôi theo chủ đề "Xanh" và chỉ có hộp kết hợp xuất hiện "Đỏ". Ý tôi là ý tưởng của chủ đề bị phá vỡ ở đây!

lưu ý bên bạn

Chỉ cần ví dụ như bạn tuyên bố Windows 8 Style là một cái gì đó của bạn không phải là một fan hâm mộ của, cũng tôi điều ngược lại. Tôi thực sự thích cái nhìn sạch sẽ và đơn giản của Windows 8.

Hộp kết hợp của tôi trông giống như nút bị tắt và tôi thậm chí không thể thay đổi nền của nó! Các nút không giống như chúng có thể nhấp được!Bất kỳ cách nào như bạn nói đây là một sự lựa chọn cá nhân, ofcourse.

Kết luận của tôi tôi sẽ chờ đợi một thời gian nếu một ai có bất kỳ đề xuất về cách tôi nhận được combobox làm việc trên cửa sổ 8. Câu trả lời của bạn mang về phía trước sự thật, vì vậy tôi sẽ được hạnh phúc để đánh dấu nó một đúng nếu Tôi không nhận được bất kỳ giải pháp thay thế nào.

Nirvan

+0

Các chủ đề mặc định tốt IMO không nhằm mục đích giữ cho giao diện giống nhau trên hệ điều hành nhưng chúng giữ cho giao diện giống nhau trên các điều khiển khác nhau trong môi trường hệ điều hành. Có ComboBox xuất hiện Blue trong Windows-7 có thể là màu đỏ trong Windows-9 và người dùng với Windows-9 có thể thực sự thích rằng hơn xem một ứng dụng sử dụng màu xanh chỉ vì đó là những gì họ nghĩ là sự lựa chọn đúng. Chủ đề của bạn nhất quán khi bạn sử dụng ComboBox với một nút và chạy nó trên Windows-8. chúng không khác biệt với phong cách mặc định với nhau. Đó là những gì chủ đề mặc định cung cấp cho bạn. – Viv

+0

Đối với mối quan tâm với việc tạo kiểu từ đầu. Một lần nữa tôi không bao giờ tạo Style từ Scratch. Hoặc sử dụng Blend và tạo nó để tạo Style of a Element dưới dạng Copy hoặc Google là Style cơ bản cho một Control, Copy nó vào và sau đó chỉnh sửa và hack đi. Cố gắng phát minh lại bánh xe có vô nghĩa. Bạn có thể lấy toàn bộ nguồn của chủ đề mặc định. Chỉ cần chỉnh sửa và tinh chỉnh nó từ đó hơn là bắt đầu tất cả hơn từ mặt đất số không – Viv

+0

Một lần nữa Theme's không phá vỡ. Nhận thức của bạn về chủ đề là khác nhau của tôi tôi đoán. Như tôi đã giải thích trong bình luận của tôi ở trên, chủ đề mặc định tiêu chuẩn hóa nhìn qua kiểm soát không phải trên các phiên bản hệ điều hành. Ví dụ đơn giản là sử dụng một khung giao diện người dùng hệ điều hành chéo như Qt hoặc các loại. họ có chủ đề và kiểm soát. Nếu để mặc định. Nút trên Windows sẽ hiển thị tương tự và khác với Nút trên Fedora. Bây giờ bạn sẽ không muốn nút Windows của bạn trông giống như Unix sẽ ya. Tôi nghĩ đó là một ý tưởng mà tôi dành cho Chủ đề và tiêu chuẩn hóa chống lại Điều khiển. – Viv

2

Cuối cùng, sau giờ thất vọng, tôi đã accross một bài giải thích here. Cuộn cho LONG ANSWER. Nó giải thích chính xác kịch bản mà tôi đã phải đối mặt đặc biệt là Kiểu Aero không được áp dụng cho Combobox của tôi. Liên kết giải thích rất rõ lý do tại sao chúng tôi cần thêm thuộc tính BasedOn vào mọi phần tử mà chúng tôi tạo kiểu nếu chúng tôi không muốn kiểu hệ điều hành mặc định được chọn. Vì vậy, thêm BasedOn này cho Combobox có nó làm việc cho tôi.

<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}"> 

Giờ đây, kiểu chủ đề Aero được sử dụng cho combobox. Như @Viv chỉ ra nó cũng có thể yêu cầu sao chép của PresentationFramework.Aero.dll và PresentationUI.dll vào máy tính Windows 8 vì chúng không được cung cấp cùng với hệ điều hành.

Cảm ơn, Nirvan

+0

Tuyệt vời! Câu trả lời hay nhất cho vấn đề này ... –

1

Tôi đã làm một chút của một hack trên mẫu được tạo sẵn. Không phải là giải pháp sạch nhất, nhưng loại bỏ các nhức đầu của việc phải cuộn mẫu của riêng tôi. Mã đằng sau về cơ bản liên kết các thuộc tính của biên giới mẫu có sẵn với các thuộc tính của hộp combo.

<Style TargetType="ComboBox"> 
    <Setter Property="Border.Background" Value="White"/> 
    <EventSetter Event="Loaded" Handler="ComboBox_Loaded"/> 
    <Style.Triggers> 
     <Trigger Property="IsReadOnly" Value="True"> 
      <Setter Property="Background" Value="Transparent"/> 
      <Setter Property="BorderBrush" Value="Transparent"/> 
     </Trigger> 
     <Trigger Property="IsFocused" Value="True"> 
      <Setter Property="Background" Value="{StaticResource ResourceKey=FocusedControlBackcolorBrush}"/> 
      <Setter Property="BorderBrush" Value="{StaticResource ResourceKey=FocusedControlBorderBrush}"/> 
     </Trigger> 
     <Trigger Property="IsMouseOver" Value="True"> 
      <Setter Property="BorderBrush" Value="{StaticResource ResourceKey=FocusedControlBorderBrush}"/> 
     </Trigger> 
    </Style.Triggers> 
</Style> 


    private void ComboBox_Loaded(object sender, RoutedEventArgs e) 
    { 
     var comboBox = sender as ComboBox; 
     var toggleButton = comboBox.Template?.FindName("toggleButton", comboBox) as ToggleButton; 
     var border = toggleButton?.Template.FindName("templateRoot", toggleButton) as Border; 
     if (border != null) 
     { 
      Binding b = new Binding("Background"); 
      b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ComboBox), 1); 
      BindingOperations.SetBinding(border, Control.BackgroundProperty, b); 

      b = new Binding("BorderBrush"); 
      b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ComboBox), 1); 
      BindingOperations.SetBinding(border, Control.BorderBrushProperty, b); 
     } 
    } 
0

Mẫu mới có Grid-> ToggleButton-> Border với màu nền cứng không tôn trọng bất kỳ kiểu nền nào. Dựa trên câu trả lời từ @Matstar tôi đã thực hiện một cách để đồng bộ hóa màu nền trên.

Bạn vẫn có thể thiết lập các ràng buộc để màu nền và mã sẽ chọn này lên và bôi lại sau này khi cần thiết:

<ComboBox ItemsSource="{Binding Values}" x:Name="Cbo2" 
Background="{Binding Path=SelectedValueBgColor}" ... /> 

Sau đó, trong xaml.cs

cbo.Loaded += (sender, args) => 
{ 
    var comboBox = sender as ComboBox; 
    if (comboBox != null) 
    { 
     var toggleButton = comboBox.Template?.FindName("toggleButton", comboBox) as ToggleButton; 
     var border = toggleButton?.Template.FindName("templateRoot", toggleButton) as Border; 
     if (border != null) 
     { 
      var existing = BindingOperations.GetBinding(comboBox, BackgroundProperty); 
      BindingOperations.SetBinding(border, BackgroundProperty, existing); 
     } 
    } 
}; 

Hãy chắc chắn rằng bạn nền ràng buộc không bao giờ trả về null

Nếu bạn không có ý nghĩa giá trị trả về trong suốt hoặc màu trắng hoặc một số giá trị mặc định khác. Nếu liên kết với một nền trả về null thì combobox sẽ ngừng hoạt động.

Đảm bảo bạn thông báo cho tài sản đã thay đổi trên nền của bạn nếu nó cần làm mới khi sự kiện diễn ra.

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