12

ユーザーがカラー ピッカー ダイアログから色を選択できるようにし、アプリケーションのスタイルをリアルタイムで変更することで、アプリケーションをよりカスタマイズしやすくしようとしています ( を使用DynamicResource) 。

にある特定のリソースを変更するにはどうすればよい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 x:Key="HeaderBackground" StartPoint="0.5,0" EndPoint="0.5,1">
        <GradientStop Color="#82cb02" Offset="1"/>
        <GradientStop Color="#82cb01" Offset="0.2"/>
        <GradientStop Color="#629a01" Offset="0.5"/>
    </LinearGradientBrush>
</Application.Resources>

この形式のカスタマイズ可能性 (基本的にはいくつかの色を変更するだけ) をアプリケーションに許可する最良の方法は何ですか?


[アップデート]

以前の質問からこの回答を見つけて試してみましたが、指定された回答のコメントに記載されているのと同じInvalidOperationException Petoj 例外が発生しています。回答のサンプルコードは次のとおりです。

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

4 に答える 4

16

ある種のスキニングをしようとしているように見えますか?

別のファイルに含まれるリソース ディクショナリでリソースを定義することをお勧めします。次に、コード (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 オブジェクトを使用して、実行時に使用している辞書を変更します。インターフェイス全体をすばやく変更するための魅力のように機能します。

于 2009-04-24T19:32:30.773 に答える
13

実行時にアプリケーション全体のリソースを変更すると、次のようになります。

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

InvalidOperationException については、WallStreet Programmer が正しいと思います。おそらく、既存のブラシを変更しようとするのではなく、必要なすべてのグラデーション ストップを使用してコードで新しいブラシを作成し、この新しいブラシをアプリケーション リソースに割り当てる必要があります。

一部の 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

于 2009-04-27T12:43:11.373 に答える
3

メソッドを使用してClone()、ブラシ (または のような他のフリーズ可能なオブジェクトStoryboard) のディープ コピーを作成し、それを使用します。

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

@WallstreetProgrammer は正しいです。すべてのアプリケーション レベルのリソースはデフォルトで凍結されています。

そのため、最初にオブジェクトを複製する必要があります。

于 2010-05-05T19:07:15.283 に答える
2

凍結されたオブジェクトを変更しようとしているため、例外が発生します。すべてのアプリケーション レベルのリソースは、凍結可能で LinearGradientBrush が可能である場合、自動的に凍結されます。ウィンドウレベルのような下位レベルに追加すると機能します。

于 2009-04-24T19:02:11.470 に答える