2009-04-24 5 views
6

사용자가 색상 선택기 대화 상자에서 색상을 선택하고 실시간으로 응용 프로그램의 스타일을 변경할 수있게하여 응용 프로그램을보다 사용자 정의 가능하게하려고합니다. (DynamicResource)WPF : 런타임 중에 App.xaml에서 리소스 (색상) 변경

app.xaml에있는 특정 리소스를 변경하려면 어떻게해야합니까?

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)); 

이쪽 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> 

최고의 무엇입니까


것은 나는이 있지만 운 (단지 테스트) 같은 것을 시도 이 양식의 사용자 정의 기능 (기본적으로 일부 색상 만 변경)을 응용 프로그램에 허용하는 방법은 무엇입니까?


난 그냥 질문 한 이전 질문에서 this answer을 발견하고,하지만 난 Petoj 주어진에 대한 코멘트에서 언급 한 같은 InvalidOperationException이 예외를 얻고 그것을 시도

[업데이트] 대답. 여기에 대한 대답에서 샘플 코드는 다음과 같습니다

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; 

답변

13

어떤 유형의 스키닝을하는 것처럼 보입니까?

별도의 파일에 포함 된 리소스 사전의 리소스를 정의하는 것이 좋습니다. 그런 다음 코드에서 당신이 그렇게으로 자원을로드 할 수 있습니다 (App.cs은 변경 후 다른 곳에서, 기본을로드) :

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

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

또한 App.xaml의 기본 리소스 사전을 정의하고 코드에서 단지 언로드 할 수 벌금.

MergedDictionaries 개체를 사용하면 런타임에 사용중인 사전을 변경할 수 있습니다. 전체 인터페이스를 빠르게 변경하기위한 매력처럼 작동합니다.

1

당신이 고정 된 개체를 수정하려고하기 때문에 예외를 얻을. freezable이고 LinearGradientBrush가있는 경우 모든 응용 프로그램 수준 리소스가 자동으로 고정됩니다. 윈도우 레벨과 같이 하위 레벨에 추가하면 효과가 있습니다.

+0

하지만이 스타일은 내 프로젝트의 모든 창에 적용되기 때문에 창에 추가 할 수 없습니다. –

6

런타임에 응용 프로그램 전체 자원을 변경하면 같은 수 있습니다 :

InvalidOperationException이 소개
Application.Current.Resources("MainBackgroundBrush") = Brsh 

, 내가 월스트리트 프로그래머를 잘 것 같다. 아마도 기존 브러시를 수정하지 말고 필요에 따라 모든 그라디언트 스톱을 가진 코드에 새 브러시를 만든 다음이 새 브러시를 응용 프로그램 리소스에 할당해야합니다.

일부 GradientStops의 색상을 변경하는 또 다른 방법은 같은 응용 프로그램 와이드 SolidColorBrushes에 DynamicResource 참조로하는 색상을 정의하는 것입니다

:

<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> 

을 한 후 사용

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

HTH

+0

이것은 내가 원했던 것입니다. –

+0

Silverlight에서는 작동하지 않습니다. 'DynamicResource'는 지원되지 않습니다. – mbomb007

2

Clone() 방법은 브러시 (또는 Storyboard 같은 다른은 Freezable 개체)의 깊은 복사본을 만들고 그것을 사용하기 :

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

@WallstreetProgrammer 잘입니다 - 모든 응용 프로그램 수준의 자원은 기본적으로 동결된다.

왜 먼저 개체를 복제해야합니까?

관련 문제