gpt4 book ai didi

c# - WPF 设计器中标记扩展参数的设计时检查

转载 作者:IT王子 更新时间:2023-10-29 04:50:44 24 4
gpt4 key购买 nike

我已经为 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 }" >

这是一个非常有用的扩展,在运行时运行良好。然而在设计时我看不到应用的样式或者如果我输入错误的粗体和斜体可能找不到它们作为静态资源。

我可以做些什么来让它工作?

扩展的源代码是

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);
}

}
}

最佳答案

更新:为 VS2012 添加了屏幕截图(工作正常)和 Blend for VS2012(部分工作:BasedOn-styles 上的基本样式不是由于某种原因正确拾取)。

还在 VS2013 PreviewBlend for VS2013 Preview 中进行了检查 - 它的部分工作原理与 Blend for VS2012 完全相同。希望他们在发布中解决这个问题。

Works in VS2012 as good as in VS2010

In Blend for VS2012 it works partionally

当您尝试在 XAML 中描述的对象具有用于实例化该对象的设计时实例的公共(public)默认构造函数时,Visual Studio 设计人员非常喜欢。

我已经更新了一些您的 CombiStyleExtension.cs 类以考虑到这一点,Visual Studio 2010 设计器现在喜欢它。但是 Blend 4 设计器仍然没有,抱歉。

看看:

using System;
using System.Linq;
using System.Windows;
using System.Windows.Markup;

namespace WpfApplication7
{
[MarkupExtensionReturnType(typeof(Style))]
public class CombiStyleExtension : MarkupExtension
{
/// <summary>
/// Set space-separated style names i.e. "size16 grey verdana".
/// </summary>
public string Names { private get; set; }

public override object ProvideValue(IServiceProvider serviceProvider)
{
return Names.Split(new[] { ' ' })
.Select(x => Application.Current.TryFindResource(x)
as Style)
.Aggregate(new Style(), RecursivelyMergeStyles);
}

private static Style RecursivelyMergeStyles(Style accumulator,
Style next)
{
if(accumulator == null || next == null)
return accumulator;

if(next.BasedOn != null)
RecursivelyMergeStyles(accumulator, next.BasedOn);

MergeStyle(accumulator, next);

return accumulator;
}

private static void MergeStyle(Style targetStyle, Style sourceStyle)
{
if(targetStyle == null || sourceStyle == null)
{
return;
}

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);
}
}
}

此标记扩展的用法也发生了一点变化。怎么样:

BasedOn="{WPF:CombiStyle bold italic }"

现在如何:

BasedOn="{WPF:CombiStyle Names='bold italic'}"

为了节省您的时间,这里有一些 xaml 用于复制-粘贴-运行-观察:

MainWindow.xaml:

<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WPF="clr-namespace:WpfApplication7"
Title="MainWindow" Height="350" Width="569">
<Window.Resources>
<!-- Did not managed to make the type-level style work -->
<!-- from app.xaml, so put it here. Just in case. -->
<Style TargetType="{x:Type Label}"
BasedOn="{WPF:CombiStyle Names='size16 grey verdana'}" />
</Window.Resources>
<StackPanel>
<Label Content="Type-level: size16 + grey + verdana" />
<Label Content="'h1': size24 + royalBlue" Style="{DynamicResource h1}" />
<Label Content="'warning': size24 + yellow + bold + shadow"
Style="{DynamicResource warning}" />
<Label Content="Inline: size12 + italic"
Style="{WPF:CombiStyle Names='size12 italic'}" />
<Label Content="Inline: size16 + bold + italic + red"
Style="{WPF:CombiStyle Names='size16 bold italic red'}" />
<Label Content="Inline: size24 + green"
Style="{WPF:CombiStyle Names='size24 green'}" />
</StackPanel>
</Window>

App.xaml:

<Application x:Class="WpfApplication7.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WPF="clr-namespace:WpfApplication7"
StartupUri="MainWindow.xaml">
<Application.Resources>
<!-- Sizes -->
<Style x:Key="size12" TargetType="Label">
<Setter Property="FontSize" Value="12" />
</Style>
<Style x:Key="size16" TargetType="Label">
<Setter Property="FontSize" Value="16" />
</Style>
<Style x:Key="size24" TargetType="Label">
<Setter Property="FontSize" Value="24" />
</Style>
<!-- Bold/Italic -->
<Style x:Key="bold" TargetType="Label">
<Setter Property="FontWeight" Value="ExtraBold" />
</Style>
<Style x:Key="italic" TargetType="Label">
<Setter Property="FontStyle" Value="Italic" />
</Style>
<!-- Colors -->
<Style x:Key="grey" TargetType="Label">
<Setter Property="Foreground" Value="#333333" />
</Style>
<Style x:Key="royalBlue" TargetType="Label">
<Setter Property="Foreground" Value="RoyalBlue" />
</Style>
<Style x:Key="green" TargetType="Label">
<Setter Property="Foreground" Value="Green" />
</Style>
<Style x:Key="yellow" TargetType="Label">
<Setter Property="Foreground" Value="Yellow" />
</Style>
<Style x:Key="red" TargetType="Label">
<Setter Property="Foreground" Value="#D00000" />
</Style>
<!-- Fonts -->
<Style x:Key="verdana" TargetType="Label">
<Setter Property="FontFamily" Value="Verdana" />
</Style>
<!-- Effects -->
<Style x:Key="shadow" TargetType="Label">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" />
</Setter.Value>
</Setter>
</Style>
<!-- Predefined Combinations -->
<Style x:Key="h1" TargetType="{x:Type Label}"
BasedOn="{WPF:CombiStyle Names='size24 royalBlue'}" />
<Style x:Key="warning" TargetType="{x:Type Label}"
BasedOn="{WPF:CombiStyle Names='size24 yellow bold shadow'}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Yellow" />
</Style>
</Application.Resources>
</Application>

享受 ;)

关于c# - WPF 设计器中标记扩展参数的设计时检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15902503/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com