Laden...

WPF MergedStyle

Letzter Beitrag vor 13 Jahren 2 Posts 3.562 Views
WPF MergedStyle

Beschreibung:

Weil ich gerade in der Situation war, zwecks Wiederverwendbarkeit einen Teil eines Styles auszulagern hab ich eine kleine Klasse geschrieben mit der man ganz praktisch mehrere Styles wieder zu einem zusammenfügen kann.


    //einmal eine allgemeine Klasse um Styles zu mergen
    public static class StyleExtensions
    {
        public static void Merge(this Style result, Style style)
        {
            if (style == null)
                return;

            if (result.TargetType.IsAssignableFrom(style.TargetType))
                result.TargetType = style.TargetType;

            if (style.BasedOn != null)
                Merge(result, style.BasedOn);

            foreach (SetterBase setter in style.Setters)
                result.Setters.Add(setter);

            foreach (TriggerBase trigger in style.Triggers)
                result.Triggers.Add(trigger);

            foreach (object key in style.Resources.Keys)
                result.Resources[key] = style.Resources[key];
        }
    }


    public class StyleWrapper : Style
    {
        public Style Style { set { this.Merge(value); } }
    }

    //und einmal die MergedStyle Klasse mit der man im XAML die Styles mergen kann
    [ContentProperty("MergedStyles")]
    public class MergedStyle : Style
    {

        private ObservableCollection<Style> _mergedStyles;
        public Collection<Style> MergedStyles
        {
            get
            {
                if (_mergedStyles == null)
                {
                    _mergedStyles = new ObservableCollection<Style>();
                    _mergedStyles.CollectionChanged += OnStylesChanged;
                }
                return _mergedStyles;
            }
        }

        private void OnStylesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (Style style in e.NewItems.Cast<Style>())
                    this.Merge(style);
            }
        }
    }

Hier kann man dann in der MergedStyles collection einfach beliebig viele Styles zusammentun.


    <Utilities:MergedStyle x:Key="{x:Type TextBox}">
         <Style TargetType="TextBox">
                <!---->
         </Style>
            
         <Utilities:StyleWrapper Style="{StaticResource MandatoryImportanceStyle}" />
    </Utilities:MergedStyle>

Lg XXX

Schlagwörter: WPF, Style, Merged

Edit: Beitrag angepasst, weil es anscheinend Probleme gibt Resourcen mehrmals in eine Collection einzubinden.

Folgendes funktioniert natürlich:


<Style x:Key"x"/>

<Element Property="{StaticResource x}"/>
<OtherElement Property="{StaticResource x}"/>

wohingegen das hier aus mir unerklärlichen Gründen nicht funktioniert:


<Style x:Key"x"/>

<Element>
    <Element.CollectionProperty>
        <StaticResource ResourceKey="x" />
    </Element.CollectionProperty>
</Element>

<OtherElement>
    <OtherElement.CollectionProperty>
        <StaticResource ResourceKey="x" />
    </OtherElement.CollectionProperty>
</OtherElement>

wenn man aber die StaticResource wieder in einem Objekt kapselt und somit nur auf ein Property anwedet dann funktionierts wieder:


<Style x:Key"x"/>

<Element>
    <Element.CollectionProperty>
        <Wrapper Property="{StaticResource x}" />
    </Element.CollectionProperty>
</Element>

<OtherElement>
    <OtherElement.CollectionProperty>
        <Wrapper Property="{StaticResource x}" />
    </OtherElement.CollectionProperty>
</OtherElement>

Strange WPF!

Lg XXX