2009-04-24 33 views
6

Tôi đang cố gắng làm cho ứng dụng của mình tùy biến hơn bằng cách cho phép người dùng chọn màu từ hộp thoại Bộ chọn màu, sau đó thay đổi kiểu của ứng dụng trong thời gian thực (với DynamicResource)WPF: Thay đổi Tài nguyên (màu) từ App.xaml trong thời gian chạy

Tôi làm cách nào để thay đổi các tài nguyên cụ thể nằm trong số app.xaml?


Tôi đã thử một cái gì đó như thế này nhưng không có may mắn (just a test):

var colorDialog = new CustomControls.ColorPickerDialog(); 
var dResult = colorDialog.ShowDialog(); 
var x = Application.Current.Resources.Values.OfType<LinearGradientBrush>().First(); 
x = new LinearGradientBrush(); 
x.GradientStops.Add(new GradientStop(colorDialog.SelectedColor,1)); 

này một đoạn trích của tập tin app.xaml:

<Application.Resources> 
     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="HeaderBackground"> 
      <GradientStop Color="#82cb02" Offset="1"/> 
      <GradientStop Color="#82cb01" Offset="0.2"/> 
      <GradientStop Color="#629a01" Offset="0.5"/> 
     </LinearGradientBrush> 

tốt nhất là gì cách để cho phép hình thức tùy chỉnh này (về cơ bản chỉ thay đổi một số màu) cho một ứng dụng?


[Cập nhật]

Tôi chỉ tìm thấy this answer từ một câu hỏi trước đó đã hỏi, và thử nó nhưng tôi nhận được cùng InvalidOperationException ngoại lệ Petoj đề cập trong các ý kiến ​​cho cho câu trả lời. Đây là đoạn mã mẫu từ câu trả lời:

XAML:

<LinearGradientBrush x:Key="MainBrush" StartPoint="0, 0.5" EndPoint="1, 0.5" > 
    <GradientBrush.GradientStops> 
     <GradientStop Color="Blue" Offset="0" /> 
     <GradientStop Color="Black" Offset="1" /> 
    </GradientBrush.GradientStops> 
</LinearGradientBrush> 

C#:

LinearGradientBrush myBrush = FindResource("MainBrush") as LinearGradientBrush; 
myBrush.GradientStops[0].Color = Colors.Red; 

Trả lời

13

Dường như bạn đang cố gắng làm một số loại da?

Tôi muốn khuyên bạn nên xác định tài nguyên trong Từ điển tài nguyên có trong một tệp riêng biệt. Sau đó, trong mã (App.cs để tải một mặc định, sau đó ở nơi khác để thay đổi), bạn có thể tải các tài nguyên như vậy:

//using System.Windows 
ResourceDictionary dict = new ResourceDictionary(); 
dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative); 

Application.Current.Resources.MergedDictionaries.Add(dict); 

Bạn cũng có thể định nghĩa từ điển tài nguyên mặc định trong App.xaml và dỡ bỏ nó trong mã chỉ khỏe.

Sử dụng đối tượng MergedDictionaries để thay đổi từ điển bạn đang sử dụng khi chạy. Hoạt động như một sự quyến rũ để thay đổi toàn bộ giao diện một cách nhanh chóng.

1

Bạn nhận được một ngoại lệ bởi vì bạn đang cố gắng để sửa đổi một đối tượng đóng băng. Tất cả các tài nguyên cấp ứng dụng sẽ tự động bị đóng băng nếu chúng là freezable và LinearGradientBrush là. Nếu bạn thêm nó ở cấp độ thấp hơn như mức cửa sổ, nó sẽ hoạt động.

+0

Nhưng tôi không thể thêm nó vào cửa sổ vì kiểu này áp dụng cho mọi cửa sổ trong dự án của tôi –

6

Thay đổi tài liệu khắp ứng dụng trong thời gian chạy là như:

Application.Current.Resources("MainBackgroundBrush") = Brsh 

Về InvalidOperationException, tôi đoán WallStreet Programmer là đúng. Có thể bạn không nên sửa đổi một cọ vẽ hiện có, mà thay vào đó hãy tạo một cọ vẽ mới với tất cả các gradient bạn cần, sau đó gán brush mới này vào các tài nguyên ứng dụng.

Một cách tiếp cận về việc thay đổi màu sắc của một số GradientStops là xác định những màu sắc như tài liệu tham khảo DynamicResource để ứng dụng SolidColorBrushes Wide như:

<LinearGradientBrush x:Key="MainBrush" StartPoint="0, 0.5" EndPoint="1, 0.5" > 
<GradientBrush.GradientStops> 
    <GradientStop Color="{DynamicResource FirstColor}" Offset="0" /> 
    <GradientStop Color="{DynamicResource SecondColor}" Offset="1" /> 
</GradientBrush.GradientStops> 

và sau đó sử dụng

Application.Current.Resources["FirstColor"] = NewFirstColorBrsh 
Application.Current.Resources["SecondColor"] = NewSecondColorBrsh 

HTH

+0

Đây chính xác là những gì tôi muốn. –

+0

Lưu ý rằng điều này không hoạt động trong Silverlight. 'DynamicResource' không được hỗ trợ. – mbomb007

2

Sử dụng Clone() phương pháp để tạo một bản sao sâu của bàn chải (hoặc bất kỳ đối tượng Freezable khác như Storyboard) và sau đó sử dụng nó:

LinearGradientBrush myBrush = FindResource("MainBrush") as LinearGradientBrush; 
myBrush = myBrush.Clone(); 
myBrush.GradientStops[0].Color = Colors.Red; 

@WallstreetProgrammer là đúng - tất cả các nguồn cấp ứng dụng bị đóng băng theo mặc định.

Thats lý do bạn cần sao chép đối tượng trước tiên.

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