在WPF设计器中设计标记扩展参数的时间

bra*_*ing 18 c# wpf markup-extensions visual-studio-designer

我为WPF编写了一个标记扩展,允许我这样做

<!-- Generic Styles -->
<Style x:Key="bold" TargetType="Label">
    <Setter Property="FontWeight" Value="ExtraBold" />
</Style>

<Style x:Key="italic" TargetType="Label">
    <Setter Property="FontStyle" Value="Italic" />
</Style>

<Style x:Key="gridHeader" TargetType="Label" 
    BasedOn="{WPF:CombiStyle bold italic }" >
Run Code Online (Sandbox Code Playgroud)

它是一个非常有用的扩展,它在运行时运行良好.但是在设计时我看不到应用的样式,或者如果我输错粗体和斜体,它们可能不会被发现为StaticResources.

我能做些什么来搞定这个?

扩展的源代码是

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Markup;

namespace MarkupExtensions
{
    [MarkupExtensionReturnType(typeof(Style))]
    public class CombiStyleExtension : MarkupExtension
    {

        private string[] MergeStyleProviders { get; set; }

        public CombiStyleExtension(string s0)
        { 
            MergeStyleProviders = s0.Split(new[]{' '});
        }

        public override object ProvideValue(IServiceProvider
                                            serviceProvider)
        {
            return MergeStyleProviders
                .Select(x => StringToStyle(serviceProvider, x))
                .Aggregate(new Style(), RecursivelyMergeStyles);
        }

        private static Style StringToStyle(IServiceProvider serviceProvider, string x)
        {
            var style = new StaticResourceExtension() { ResourceKey = x }.ProvideValue(serviceProvider) as Style;
            if (style==null)
            {
                throw new ArgumentException("Argument could not be converted to a style");
            }
            return style;
        }

        private static Style RecursivelyMergeStyles(Style accumulator,
                                           Style next)
        {
            if (next.BasedOn != null)
            {
                RecursivelyMergeStyles(accumulator, next.BasedOn);
            }

            MergeStyle(accumulator, next);

            return accumulator;
        }

        private static void MergeStyle(Style targetStyle, Style sourceStyle)
        {
            targetStyle.TargetType = sourceStyle.TargetType;
            // Merge the Setters...
            foreach (var setter in sourceStyle.Setters)
                targetStyle.Setters.Add(setter);

            // Merge the Triggers...
            foreach (var trigger in sourceStyle.Triggers)
                targetStyle.Triggers.Add(trigger);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

McD*_*ean 0

不不幸的是,我对问题的理解是这样的,

由于依赖属性,设计时解析似乎在 WPF 中有效。由于MarkupExtension不是从依赖对象派生的,因此您的扩展在设计时不会被评估。至于天气是疏忽还是有意为之,值得商榷。

可能还有另一种方法来解决这个问题,尽管它会略有不同。创建一个名为 MergeStyles 的新附加属性。在该属性中,您可以指定要合并和应用的样式名称。当值更改时,只需使用上面的代码更新附件的样式即可。您可以使用要合并的每个样式所处的位置来确定层次结构。

这并不完全是您想要的,但它可能会让您成功一半。结果是你可以绑定它。