Laden...

"FooExtension" ist für "Setter.Value" nicht gültig. Unterstützt werden nur die MarkupExtension-Type

Erstellt von d.jonas vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.398 Views
Thema geschlossen
D
d.jonas Themenstarter:in
21 Beiträge seit 2017
vor 5 Jahren
"FooExtension" ist für "Setter.Value" nicht gültig. Unterstützt werden nur die MarkupExtension-Type

Hallo zusammen,

ich habe das Problem das seit Neustem meine "MarkupExtensions" nicht mehr in VisualStudio sauber funktionieren. Dabei erhalte ich immer folgenden Fehler:

Fehlermeldung:

ArgumentException: "ThemeExtension" ist für "Setter.Value" nicht gültig. Unterstützt werden nur die MarkupExtension-Typen "DynamicResourceExtension" und "BindingBase" oder abgeleitete Typen.
bei System.Windows.Setter.Seal()
bei System.Windows.SetterBaseCollection.Seal()
bei System.Windows.Style.Seal()
bei System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache)
bei System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
bei System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
bei System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
bei System.Windows.Controls.TextBox.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
bei System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
bei System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
bei System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
bei System.Windows.FrameworkElement.UpdateStyleProperty()
bei System.Windows.FrameworkElement.OnInitialized(EventArgs e)
bei System.Windows.FrameworkElement.TryFireInitialized()
bei System.Windows.FrameworkElement.EndInit()
bei MS.Internal.Xaml.Runtime.ClrObjectRuntime.InitializationGuard(XamlType xamlType, Object obj, Boolean begin)

Dies hat nun seid gut 6 Wochen ohne Probleme funktioniert und von heute auf Morgen spackt mein VS rum und ich kann nicht mehr arbeiten. Auch Blend schafft es nicht. Sobald ich den Code ausführe läuft das alles wie es soll. Ändere ich ein Zeichen in meinem XAML Code wird dieser auch fehlerfrei angezeigt und sauber kompilliert (design time).

Ich habe dazu bereits auf SO einen Post erstellt, ebenso beim Bug Tracker von VSCommunity:

Mehr Details befindet sich im SO Post. Sollte es erwünscht sein, werde ich diesen hier nochmals komplett schreiben.

Ich habe im Internet ein Beispielprojekt gefunden. Bei diesem tritt genau das selbe Phänomen auf!:

Ist das Problem bereits bei einem von euch aufgetreten?

Danke schonmal!

ThemeExtension.cs

[MarkupExtensionReturnType(typeof(Color))]
public class ThemeColorExtension : ThemeExtension
{
    internal override object ModifyThemeValue(object value)
    {
        if (value is SolidColorBrush solidColorBrush)
            return solidColorBrush.Color;
        return value;
    }
}

[MarkupExtensionReturnType(typeof(SolidColorBrush))]
public class ThemeExtension : MarkupExtension
{
    // ##############################################################################################################################
    // Properties
    // ##############################################################################################################################

    #region Properties

    // ##########################################################################################
    // Public Properties
    // ##########################################################################################

    /// <summary>
    /// The Key in the Resource Theme file
    /// </summary>
    public string Key { get; set; }

    // ##########################################################################################
    // Private Properties
    // ##########################################################################################

    private static readonly List<ThemeExtension> _Cache = new List<ThemeExtension>();
    private static readonly ResourceDictionary _DefaultTheme;
    private static ResourceDictionary _CurrentTheme;

    private PropertyInfo _Property { get; set; }
    private DependencyProperty _DependencyProperty { get; set; }
    private WeakReference _TargetReference { get; set; }

    #endregion

    // ##############################################################################################################################
    // Constructor
    // ##############################################################################################################################

    #region Constructor

    static ThemeExtension()
    {
        _DefaultTheme = new ResourceDictionary
        {
            Source = new Uri("/HtPlcFramework;component/Themes/DefaultTheme.xaml", UriKind.Relative)
        };
        _CurrentTheme = _DefaultTheme;

        NavigationService.Navigated += _OnNavigated;
    }

    public ThemeExtension() { }

    #endregion

    // ##############################################################################################################################
    // public methods
    // ##############################################################################################################################

    #region public methods

    /// <summary>
    /// https://social.msdn.microsoft.com/Forums/vstudio/en-US/931d7bff-90b6-4a70-bb0b-3a097e1301a1/net-40-breaking-change-using-a-markup-extension-as-value-of-property-setter-in-xaml-style?forum=wpf
    /// </summary>
    /// <param name="serviceProvider"></param>
    /// <returns></returns>
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        if (target == null)
            return this;

        if (target.TargetObject != null && target.TargetProperty != null)
        {
            _TargetReference = new WeakReference(target.TargetObject);
            if (target.TargetProperty.GetType() == typeof(PropertyInfo))
            {
                _Property = (PropertyInfo)target.TargetProperty;
            }
            else if (target.TargetProperty is DependencyProperty)
            {
                _DependencyProperty = (DependencyProperty)target.TargetProperty;
            }
        }

        if (!_Cache.Contains(this))
            _Cache.Add(this);

        return ModifyThemeValue(_ReadThemeKey(Key));
    }

    /// <summary>
    /// Change the Theme set
    /// </summary>
    /// <param name="themeUri">Default is: new Uri("/HtPlcFramework;component/Themes/DefaultTheme.xaml", UriKind.Relative)</param>
    public static void ChangeTheme(Uri themeUri)
    {
        _CurrentTheme = new ResourceDictionary { Source = themeUri };

        foreach (ThemeExtension reference in _Cache)
        {
            reference._UpdateTheme();
        }
    }

    /// <summary>
    /// Get the current theme entry. Can be null!
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public static object ReadThemeKey(string key) => _ReadThemeKey(key);

    internal virtual object ModifyThemeValue(object value)
    {
        return value;
    }

    #endregion

    // ##############################################################################################################################
    // private methods
    // ##############################################################################################################################

    #region private methods

    private static void _OnNavigated(object sender, string layer)
    {
        _Cache.RemoveAll(ti => !ti._TargetReference.IsAlive);
    }

    private static object _ReadThemeKey(string key)
    {
        try
        {
            return _CurrentTheme[key] ?? _DefaultTheme[key];
        }
        catch (Exception)
        {
            Trace.WriteLine($"The key '{key}' was not found in {_CurrentTheme.Source}!");
            return null;
        }
    }

    private void _UpdateTheme()
    {
        if (_TargetReference.IsAlive)
        {
            if (_Property != null)
                _Property.GetSetMethod().Invoke(_TargetReference.Target, new object[] { _ReadThemeKey(Key) });
            else if (_DependencyProperty != null)
            {
                DependencyObject dependencyObject = _TargetReference.Target as DependencyObject;
                dependencyObject?.SetValue(_DependencyProperty, _ReadThemeKey(Key));
            }
        }
        else
        {
            _Cache.Remove(this);
        }
    }

    #endregion

} 
1.040 Beiträge seit 2007
vor 5 Jahren

Wie sieht denn die MarkupExtension aus?

D
d.jonas Themenstarter:in
21 Beiträge seit 2017
vor 5 Jahren

Habe meinen Post editiert..

1.040 Beiträge seit 2007
vor 5 Jahren

Es wäre ganz gut, wenn du z.B. auch die Verwendung der MarkupExtension hier nochmal zeigen würdest, also einfach alle notwendigen Infos. Keiner hat Lust sich die Infos aus einem anderen Beitrag rauszusuchen.

Bzgl. des Fehlers, evtl. kannst du das mal probieren:
[Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden

16.834 Beiträge seit 2008
vor 5 Jahren

Verlink schön und gut; trotzdem unterliegt der Beitrag den Cross Posting Regeln und ist daher erst mal dicht.
[Hinweis] Wie poste ich richtig? 2.2 Keine Crossposts

Den Post bei SO und hast Du auch erst gestern erstellt. Tanzt immer auf mehreren Parties zeitgleich?
Es ist einfach nicht fair, potentielle Helfer doppele Arbeit machen zu lassen. Auch die anderen Foren haben wegen genau sowas recht strenge Cross Posting Regeln; auf SO bzw. SE kann das auch zurecht zum generellen Kick führen.

Thema geschlossen