2013-07-22 40 views
9

Visual Studio 2010 | .NET/WPF 4.0Màu DynamicResource không hoạt động cho BorderBrush trên một Border - Bug?

Tôi nghĩ rằng đây có thể là một lỗi WPF, nhưng tôi dường như không thể tìm thấy một báo cáo lỗi về nó. Để trang trải khả năng rằng tôi chỉ thiếu một cái gì đó hiển nhiên, tôi chuyển sang stackoverflow cho câu trả lời!

xem xét XAML này (không có gì trong codebehind):

<Window x:Class="DownExpanders.BorderTest" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="BorderTest" Height="300" Width="300"> 
    <Window.Resources> 
     <Color x:Key="BackgroundColor" R="255" G="0" B="0" A="255"/> 
     <Color x:Key="BorderColor" R="0" G="0" B="255" A="255"/> 
     <SolidColorBrush x:Key="BorderColorBrush" Color="{DynamicResource BorderColor}"/> 
    </Window.Resources> 
    <Grid> 
     <Border BorderThickness="20"> 
      <Border.Background> 
       <SolidColorBrush Color="{DynamicResource BackgroundColor}"/> 
      </Border.Background> 
      <Border.BorderBrush> 
       <SolidColorBrush Color="{DynamicResource BorderColor}"/> 
      </Border.BorderBrush> 
     </Border> 

     <Border Margin="40" BorderBrush="{DynamicResource BorderColorBrush}" BorderThickness="20"/> 
    </Grid> 
</Window> 

Trong nhà thiết kế, nó ám như mong đợi. Đường viền ngoài có viền màu xanh lớn và nền đỏ, đường viền bên trong có đường viền màu xanh lớn. Tuyệt quá.

Khi tôi chạy mã, đường viền ngoài có đường viền KHÔNG - có vẻ như nó không tải. Nền được đặt thành màu đỏ chính xác. Trong khi đó, đường viền bên trong không tải đường viền màu xanh của nó một cách chính xác.

Nếu tôi thay đổi tất cả "DynamicResource" thành "StaticResource", nó sẽ hiển thị chính xác khi chạy. Các mâu thuẫn thực sự là bugging tôi, và tôi không thể hình dung nó ra \

Vì vậy:.

  1. Tại sao không làm việc DynamicResource cho BorderBrush?
  2. Cho số 1, tại sao hiện hoạt động cho nền?
  3. Tại sao xác định rõ ràng bàn chải màu đồng nhất trong tài nguyên dường như khắc phục được sự cố?

EDIT:

Hình như đó là một lỗi mà MS quyết định không sửa chữa (nhờ Sheridan cho liên kết): http://connect.microsoft.com/VisualStudio/feedback/details/589898/wpf-border-borderbrush-does-not-see-changes-in-dynamic-resource

+0

Thú vị, vẫn xảy ra trong. 4.5.50760 vì vậy nếu đó là lỗi mà họ chưa khắc phục được. – Andy

+0

Ye chắc chắn sẽ nghĩ rằng đó là một lỗi. Bạn cũng có thể thêm vào báo cáo lỗi của bạn, Snoop báo cáo bàn chải của đường viền bên ngoài là 'Minh bạch' (Không có lỗi) và vấn đề này không xảy ra nếu bạn chỉ đặt Brush trực tiếp ngay cả đối với đường viền ngoài như trong' BorderBrush = "{DynamicResource BorderColorBrush } "'. Do đó trông giống như một vấn đề của khi SolidColorbrush cho BorderBrush đang được tạo ra từ một DynamicResource ** Màu **, nó được mọi thứ hơi say lên. Không chắc chắn có thể một số trường hợp lạ của cố gắng để khóa tài nguyên/truy cập chúng – Viv

+1

oh cái gì khác tôi chỉ thấy quá, Nếu bạn di chuyển các nguồn lực đến một phạm vi cao hơn, nói 'App.xaml', nó hoạt động tốt cho mã chính xác của bạn – Viv

Trả lời

2

Rõ ràng, câu trả lời cho câu hỏi của bạn là không, hành vi này là không một lỗi.

Vấn đề này đã được đăng trên trang web của Microsoft Connect bởi một người dùng và trả lời sau đây đã được đưa ra:

DynamicResources đang "nhìn lên" trong thời gian chạy chứ không phải là thời gian biên dịch. "Động" đề cập đến không "có thể được cập nhật động bất cứ lúc nào" nhưng "chúng tôi sẽ tra cứu sau, khi thực sự cần thiết".

Nếu bạn muốn thay đổi bàn chải đường viền khi chạy, bạn cần phải áp dụng thuộc tính Name = "" cho Đường viền để chạm vào từ mã số hoặc bạn có thể sử dụng Ràng buộc để đặt giá trị của bàn chải là một DependencyProperty (nếu bạn đang sử dụng mẫu MVVM hoặc một cái gì đó tương tự ).Thay đổi thuộc tính và cọ vẽ đường viền được cập nhật bởi hệ thống ràng buộc .

BTW, đây có thể là một câu hỏi hay tại StackOverflow - "Tại sao không phải là DynamicResource của tôi đang được cập nhật?"

Cá nhân, tôi thích dòng cuối cùng nhất. Microsoft hữu ích nhất của nó! Trang có thể được tìm thấy here.

+2

Tôi chấp nhận phản hồi đó từ Microsoft nếu đó là hành vi nhất quán. Background chỉ tải tốt. Chỉ BorderBrush có vấn đề. Trong thực tế, OP của lỗi đó ghi nhận cùng một điều, và phản ứng MS là "chúng tôi không sửa chữa nó." Vâng, tôi đoán có câu trả lời. Cung cấp cho bạn dấu kiểm để tìm báo cáo lỗi: P – pfw

+0

Tôi đã tạo một công việc đơn giản xung quanh: http://stackoverflow.com/questions/19427351/change-dynamicresource-color-value-during-runtime/19429175#19429175 –

2

này dường như không phải là trường hợp với RadialGradientBrush.

<Window x:Class="WpfApplication3.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 

    <Grid> 
     <Grid.Resources> 
      <Color x:Key="BackgroundColor" R="255" G="0" B="0" A="255"/> 
      <Color x:Key="BorderColor" R="0" G="0" B="255" A="255"/> 
      <SolidColorBrush x:Key="BorderColorBrush" Color="{DynamicResource BorderColor}"/> 
     </Grid.Resources> 
     <Border BorderThickness="20"> 
      <Border.BorderBrush> 
       <RadialGradientBrush> 
        <GradientStop Color="{DynamicResource BorderColor}"/> 
        <GradientStop Color="{DynamicResource BorderColor}"/> 
       </RadialGradientBrush> 
      </Border.BorderBrush> 
      <Border.Background> 
       <SolidColorBrush Color="{DynamicResource BackgroundColor}"/> 
      </Border.Background> 
     </Border> 

     <Border Margin="40" BorderBrush="{DynamicResource BorderColorBrush}" BorderThickness="20"/> 

    </Grid> 
</Window> 

enter image description here

1

Một điều thú vị là nó không xảy ra khi sử dụng một Rectangle thay vì một biên giới.

<Rectangle StrokeThickness="20"> 
     <Rectangle.Stroke> 
      <SolidColorBrush Color="{DynamicResource BorderColor}"/> 
     </Rectangle.Stroke> 
     <Rectangle.Fill> 
      <SolidColorBrush Color="{DynamicResource BackgroundColor}"/> 
     </Rectangle.Fill> 
    </Rectangle> 
0

Dường như nó được cố định trong 4.5. Trong trường hợp của tôi nó hoạt động trong Windows 8, nhưng không hoạt động trong Windows XP (không có .net 4.5).

0

Dưới đây là một điều khiển tùy chỉnh mà bạn có thể sử dụng thay cho Đường viền. Nó khắc phục sự cố với thuộc tính BorderBrush. Nó sử dụng hình chữ nhật làm việc như một câu trả lời cho biết. Xin lưu ý rằng điều khiển này có thể sẽ không phù hợp với hiệu suất của việc sử dụng kiểm soát Biên giới nhưng nó hoạt động, vì vậy tôi đề nghị chỉ sử dụng nó khi cần thiết.

<Style TargetType="{x:Type controls:BorderFix}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type controls:BorderFix}"> 
       <DockPanel x:Name="PART_Container" 
          Background="{TemplateBinding Background}" 
          LastChildFill="True" 
          UseLayoutRounding="{TemplateBinding UseLayoutRounding}"> 
        <Rectangle x:Name="PART_LeftBorder" 
           DockPanel.Dock="Left" 
           Fill="{TemplateBinding BorderBrush}" 
           Width="{Binding Path=BorderThickness.Left, RelativeSource={RelativeSource TemplatedParent}}"/> 
        <Rectangle x:Name="PART_TopBorder" 
           DockPanel.Dock="Top" 
           Fill="{TemplateBinding BorderBrush}" 
           Height="{Binding Path=BorderThickness.Top, RelativeSource={RelativeSource TemplatedParent}}"/> 
        <Rectangle x:Name="PART_RightBorder" 
           DockPanel.Dock="Right" 
           Fill="{TemplateBinding BorderBrush}" 
           Width="{Binding Path=BorderThickness.Right, RelativeSource={RelativeSource TemplatedParent}}"/> 
        <Rectangle x:Name="PART_BottomBorder" 
           DockPanel.Dock="Bottom" 
           Fill="{TemplateBinding BorderBrush}" 
           Height="{Binding Path=BorderThickness.Bottom, RelativeSource={RelativeSource TemplatedParent}}"/> 
        <ContentPresenter x:Name="PART_Content"/> 
       </DockPanel> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

public sealed class BorderFix : ContentControl 
{ 
    static BorderFix() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(BorderFix), new FrameworkPropertyMetadata(typeof(BorderFix))); 
    } 
} 

Thực tế là chúng ta phải làm điều này là vô lý. Một câu trả lời khác cho thấy rằng lỗi này được sửa trong phiên bản .NET được sử dụng bởi Windows 8. Tôi chưa thử nghiệm nhưng chúng tôi hy vọng điều đó là chính xác. .NET 4.5.51209 trưng bày cùng một vấn đề.