2010-03-19 25 views
25

Tôi đang cố gắng tìm hiểu điều gì đó về WPF và tôi khá ngạc nhiên bởi tính linh hoạt của nó.WPF Một số kiểu không được áp dụng trên các điều khiển DataTemplate

Tuy nhiên, tôi đã gặp sự cố với Style s và DataTemplate s, điều này hơi khó hiểu. tôi đã xác định bên dưới trang thử nghiệm để chơi xung quanh một chút với phong cách vv và phát hiện ra rằng Style s quy định tại <Page.Resources> cho BorderTextBlock không được áp dụng trong DataTemplate, nhưng Style cho ProgressBar quy định tại chính xác theo cùng một cách được áp dụng.

Source code (tôi chỉ sử dụng Kaxaml và XamlPadX để xem kết quả)

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <Page.Resources> 

    <Style TargetType="{x:Type Border}"> 
     <Setter Property="Background" Value="SkyBlue"/> 
     <Setter Property="BorderBrush" Value="Black"/> 
     <Setter Property="BorderThickness" Value="2"/> 
     <Setter Property="CornerRadius" Value="5"/> 
    </Style> 

    <Style TargetType="{x:Type TextBlock}"> 
     <Setter Property="FontWeight" Value="Bold"/> 
    </Style> 

    <Style TargetType="{x:Type ProgressBar}"> 
     <Setter Property="Height" Value="10"/> 
     <Setter Property="Width" Value="100"/> 
     <Setter Property="Foreground" Value="Red"/> 
    </Style> 

    <XmlDataProvider x:Key="TestData" XPath="/TestData"> 
     <x:XData> 
     <TestData xmlns=""> 
      <TestElement> 
      <Name>Item 1</Name> 
      <Value>25</Value> 
      </TestElement> 
      <TestElement> 
      <Name>Item 2</Name> 
      <Value>50</Value> 
      </TestElement> 
     </TestData> 
     </x:XData> 
    </XmlDataProvider> 

    <HierarchicalDataTemplate DataType="TestElement"> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" Margin="5,5" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="{Binding XPath=Name}"/> 
      <ProgressBar Value="{Binding XPath=Value}"/> 
     </StackPanel> 
     </Border> 
    </HierarchicalDataTemplate> 

    </Page.Resources> 

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> 
    <StackPanel Orientation="Vertical" VerticalAlignment="Center"> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="Item 1"/> 
      <ProgressBar Value="25"/> 
     </StackPanel> 
     </Border> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="Item 2"/> 
      <ProgressBar Value="50"/> 
     </StackPanel> 
     </Border> 
    </StackPanel> 
    <ListBox Margin="10,10" Width="140" ItemsSource="{Binding Source={StaticResource TestData}, XPath=TestElement}"/> 
    </StackPanel> 
</Page> 

tôi nghi ngờ nó có cái gì để làm với kiểu mặc định vv, nhưng nhiều hơn khó hiểu là tại sao một số Style s được áp dụng và một số không . Tôi không thể tìm thấy một lời giải thích dễ dàng ở trên bất cứ đâu và do đó muốn hỏi xem có ai đó sẽ tử tế để giải thích hành vi này theo các thuật ngữ của lamens với các liên kết có thể có tới mô tả kỹ thuật, ví dụ như MSDN hay không.

Cảm ơn bạn đã hỗ trợ!

Trả lời

27

Điều này thực sự là do thiết kế. Các phần tử không lấy được từ Điều khiển sẽ không nhận các Kiểu ẩn, trừ khi chúng nằm trong tài nguyên ứng dụng.

Điều này link giải thích điều này chi tiết hơn hoặc bạn có thể xem Connent bug report.

+0

Cảm ơn bạn đã liên kết! Nó giải thích những gì đang xảy ra, nhưng vẫn liên kết đến tài liệu chính thức sẽ được tốt đẹp chỉ là tôi biết nơi để tìm những thứ như vậy. – Martin

+0

Đã thêm liên kết vào báo cáo lỗi trên trang Kết nối của Microsoft, không chắc chắn có bất kỳ tài liệu chính thức nào mô tả hành vi này. – CodeNaked

+0

cả hai liên kết đều đã chết. tìm thấy [liên kết đường dẫn đầu tiên] (https://web.archive.org/web/20170201072114/http://www.11011.net/archives/000692.html). Vui lòng thêm nó vào câu trả lời của bạn nếu bạn muốn. – itsho

3

Tôi cũng đã xem xét điều này và cá nhân tôi nghĩ đó là lỗi. Tôi đã nhận thấy rằng phong cách được thiết lập nếu bạn đặt tên cho phong cách của bạn như vậy:

<Style x:Key="BorderStyle" TargetType="{x:Type Border}"> 
etc... 

và thiết lập một cách rõ ràng DataTemplate của bạn để sử dụng những phong cách:

<HierarchicalDataTemplate DataTemplate="TestElement"> 
    <Border Height="45" Width="120" Margin="5,5", Style="{StaticResource BorderStyle}"> 

tôi nghĩ rằng nó có thể là cho DataTemplates (và có thể ControlTemplates), chúng mặc định có kiểu null, trừ khi bạn đặt chúng một cách rõ ràng.

Đối với tôi không có nghĩa là để xảy ra - nó không phải là một cách logic của WPF làm việc ...

0

Điều này là do ListBox là một phụ huynh logic của mục datatemplate bạn, bây giờ nhớ, tất cả các thuộc tính đó là những "thừa kế "như phông chữ, forecolor vv, có nguồn gốc từ cha mẹ hợp lý và ListBox đã ghi đè nó theo kiểu mặc định của riêng nó, đó là lý do tại sao điều này sẽ không hoạt động. Tuy nhiên trong trường hợp này, bạn có thể sử dụng kiểu có tên như ông Dave đã gợi ý, nhưng tôi nghĩ nếu nó không hoạt động thì đây là một vấn đề đã biết trong trường hợp Danh sách hộp vv, bạn có thể đặt câu hỏi của tôi here, i had similar problem in listbox và câu trả lời trong câu hỏi của tôi là chi tiết hơn.

23

Tôi đã phát hiện ra một giải pháp đơn giản cho việc này. Đối với bất kỳ phần tử nào không thể tìm kiếm bên ngoài ranh giới đóng gói mẫu dữ liệu (nghĩa là không được theo kiểu ngầm), bạn chỉ có thể khai báo kiểu trống trong mẫu dữ liệu cho loại phần tử đó và sử dụng thuộc tính BasedOn của kiểu để tìm sửa đúng kiểu ẩn bên ngoài mẫu dữ liệu để áp dụng.

Trong ví dụ bên dưới, Hộp văn bản có thể tìm kiếm bên ngoài ranh giới đóng gói mẫu dữ liệu (vì nó kế thừa từ Kiểm soát?), nhưng TextBlock không thể, vì vậy tôi khai báo kiểu trống cho nó có thể tìm kiếm bên ngoài mẫu dữ liệu.

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <DataTemplate.Resources> 
      <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}" /> 
     </DataTemplate.Resources> 
     <DockPanel> 
      <TextBlock Text="{Binding Name}" /> 
      <TextBox Text="{Binding Value}" /> 
     </DockPanel> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 
Các vấn đề liên quan