我试图让我的应用程序更加个性化,允许用户挑选从拾色器对话框选择一种颜色,然后改变实时(与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 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>

<强>什么是允许这种形式的可定制性(基本上只是改变一些颜色)到应用程序?的最佳方式


<强> [更新]

我刚刚发现从以前的问题,这个答案是有人问,并试图,但我收到同样的出现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;
有帮助吗?

解决方案

它看起来像你试图做一些剥皮的?

我建议定义包含在一个单独的文件中的一个资源字典的资源。然后,在码(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反对改变你使用在运行时的字典。就像对于快速变化的整个接口一个魅力。

其他提示

在运行时改变应用范围的资源是这样的:

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

关于InvalidOperationException异常,我想华尔街程序员是正确的。 也许你不应该试图修改现有的刷子,而是在代码中创建一个新的刷你需要的所有gradientstops,然后分配应用程序资源,这个新的画笔。

在改变某些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

使用Clone()方法使刷子的深层副本(或任何其它可冷冻的物体,像Storyboard),然后使用它:

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

@WallstreetProgrammer是正确的 - 所有的应用程序级资源是默认冷冻

这就是为什么你需要先克隆对象。

因为你试图修改冻结的对象你会得到一个例外。如果他们是可冻结和一个LinearGradientBrush是所有应用程序级别的资源会被自动冻结。如果添加它在一个较低的水平像窗位,将工作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top