WPF: تغيير الموارد (الألوان) من App.xaml أثناء وقت التشغيل

StackOverflow https://stackoverflow.com/questions/786183

سؤال

أحاول أن أجعل تطبيقي أكثر قابلية للتخصيص من خلال السماح للمستخدمين باختيار لون من مربع حوار منتقي الألوان، ثم تغيير نمط التطبيق في الوقت الفعلي (مع 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

حول InvalentOperationException، أعتقد أن مبرمج WallStreet هو الصحيح. ربما يجب ألا تحاول تعديل فرشاة موجودة، ولكن بدلا من ذلك إنشاء فرشاة جديدة في التعليمات البرمجية مع جميع المتظاهرات التي تحتاجها، ثم قم بتعيين هذه الفرشاة الجديدة في موارد التطبيق.

يتمثل نهج آخر في تغيير لون بعض المتظاهرات في تحديد تلك الألوان كمراجع Dynamicresource لتطبيق Solidcolorbrushes Wide SolidColorbrushes مثل:

<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

هذر

استخدم ال Clone() طريقة لجعل نسخة عميقة من الفرشاة (أو أي كائن قابل للتجميل آخر مثل Storyboard) ثم استخدمه:

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

pallstreetprogrammer هو الصحيح - يتم تجميد جميع موارد مستوى التطبيق بشكل افتراضي.

هذا هو السبب في أنك تحتاج إلى استنساخ الكائن أولا.

تحصل على استثناء لأنك تحاول تعديل كائن مجمد. يتم تجميد جميع موارد مستوى التطبيق تلقائيا إذا كانت قابلة للتجميل و LineARGradientBrush. إذا قمت بإضفته على مستوى أقل مثل مستوى النافذة، فسوف يعمل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top