我想创建一些扩展的Binding-Markup-Extension,它的行为就像普通的WPF-Binding一样,但做的更多(使用不同的默认值,可能会添加一些行为等).代码如下所示:
public class CustomBindingExtension : Binding
{
.. some extra properties and maybe overrides ...
}
Run Code Online (Sandbox Code Playgroud)
这一切都很好,包括XAML-intellisense,除了我不能让Resharper正确解析我的Binding-Path.即:使用此代码我可以[Strg] +单击'CurrentText',Resharper让vs2010导航到定义CurrentText-Property的代码.
<UserControl x:Name="uc" ...>
<TextBox Text="{Binding ViewModel.CurrentText, ElementName=uc}" />
</UserControl>
Run Code Online (Sandbox Code Playgroud)
但是使用我的绑定,它在运行时正常工作,我只是在悬停'CurrentText'时得到一个工具提示告诉我它是'MS.Internal.Design.Metadata.ReflectionTypeNode',并且没有通过[Strg] + Click导航.
<UserControl x:Name="uc" ...>
<TextBox Text="{util:CustomBinding ViewModel.CurrentText, ElementName=uc}" />
</UserControl>
Run Code Online (Sandbox Code Playgroud)
我尝试了以下事项:
我还查看了原始类Binding和BindingBase,但找不到我的代码的任何更多差异.任何想法应该有什么帮助?或者这只是对Binding-MarkupExtension的特殊处理,我无法获得自己的MarkupExtensions?
更新2011年3月16日:也可能是错误或ReSharper的不足,Jetbrains的正在调查该问题:http://youtrack.jetbrains.net/issue/RSRP-230607
更新10.12.2013:同时,该功能似乎正在工作(使用R#7.1.3,也许是早期版本),我实际上使用BindingDecoratorBase的方法,我非常喜欢它.也许它只有作用,如果你的MarkupExtension结束'Binding',但我的确如此,所以我很高兴.
我们刚刚从vs2008切换到vs2010,我们的项目编译运行良好,没有任何问题.但是,xaml设计器有一些错误.这是其中一个错误,希望有人可以提供解决方案.
我们有一个自定义的MarkupExtension,我们在xaml中使用它来获取某些资源.像这样的东西:
<Button Style="{l:GetResource Key=MyButtonStyle}" />
我知道我们可以使用StaticResource或DynamicResource.但是我们有理由使用自定义markupextension.
设计者的错误消息是:
'GetResourceExtension'对Setter.Value无效.唯一受支持的MarkupExtension类型是
DynamicResourceExtension
和/BindingBase
或派生类型.
我的问题是代码在vs2008中运行良好,并且在2010年运行良好,如何使2010设计师工作?
我正在谈论扩展,例如x:Reference
和x:FactoryMethod
集体出现在这里.我在网上阅读了很多相互矛盾的信息,包括MSDN,Stackoverflow和其他来源.
我将以x:Reference
一个例子来谈谈,但我实际上也指的是其他标记扩展.混淆的主要原因是以下MSDN摘录:
在WPF中,您可以使用XAML 2009功能,但仅适用于非WPF标记编译的XAML.标记编译的XAML和BAML形式的XAML目前不支持XAML 2009语言关键字和功能.请注意,在WPF中加载松散XAML的现有技术也可能对CLR类型和类型系统提供安全性和访问限制,这些限制比标记编译的XAML更具限制性.有关更多信息,请参阅安全性(WPF)或WPF安全策略 - 平台安全性.XAML 2009还引入了其他功能,可以修改以前的XAML 2006构造或修改基本标记形式.
x:Reference是在XAML 2009中定义的构造.在WPF中,您可以使用XAML 2009功能,但仅适用于非WPF标记编译的XAML.标记编译的XAML和BAML形式的XAML目前不支持XAML 2009语言关键字和功能.
但是,以下段落出现在前一段之前(即关于一段x:Reference
).
在WPF和XAML 2006中,元素引用由ElementName绑定的框架级功能处理.对于大多数WPF应用程序和方案,仍应使用ElementName绑定.此一般指导的例外情况可能包括存在数据上下文或其他作用域考虑因素的情况,这些因素使得数据绑定不切实际且不涉及标记编译.
这里没有直接的矛盾,但这一段似乎说可以x:Reference
在应用程序中使用.此外,该段落x:Reference
似乎是自动生成的,可能已经过时.
然后,我们从"WPF 4 Unleashed"一书中摘录如下:
x:引用标记扩展通常与XAML2009功能错误关联,这些功能只能在撰写本文时从松散的XAML中使用.虽然x:Reference是WPF 4中的一个新功能,但只要您的项目针对.NET Framework的版本4或更高版本,就可以在XAML2006中使用它.
我们还有以下Stackoverflow问题,其中一些有相互矛盾的答案,而且没有一个明显正确:
最后,我个人使用了x:Reference
扩展,它似乎在WPF应用程序中工作,无论MSDN说什么,即使Visual Studio有时会抱怨奇怪的东西(或者它可能是ReSharper),例如标记中的空引用异常.
了解实际问题,
我为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 …
Run Code Online (Sandbox Code Playgroud) 如果我有一个名为MyObject的对象,它有一个名为MyChild的属性,它本身有一个名为Name的属性.如果我拥有的只是一个绑定路径(即"MyChild.Name"),并且对MyObject的引用,我该如何获取该Name属性的值?
MyObject
-MyChild
-Name
Run Code Online (Sandbox Code Playgroud) 我正在开发WPF MarkupExtension并在设计时遇到错误.使用以前版本的Visual Studio 2010,可以启动Visual Studio 2010的第二个实例并附加到已运行实例的进程,设置断点并调试设计时行为.
但是在Visual Studio 2012中,我也可以附加到另一个Visual Studio 2012的进程,但是在第二个实例中没有加载符号,因此我无法像使用Visual Studio 2010那样调试设计时间.
如何运行此调试器?
我试过的事情:
wpf design-time markup-extensions visual-studio visual-studio-debugging
我在网上看到了两种不同的方法来增强IValueConverter.其中一个从MarkupExtension扩展了ValueConverter,另一个从DependencyObject扩展.我无法从两者延伸,所以我想知道是否有一个比另一个好?
我正在使用XAML序列化作为对象图(在WPF/Silverlight之外),我正在尝试创建一个自定义标记扩展,它允许使用对XAML中其他地方定义的集合的选定成员的引用来填充集合属性.
这是一个简化的XAML代码片段,演示了我的目标:
<myClass.Languages>
<LanguagesCollection>
<Language x:Name="English" />
<Language x:Name="French" />
<Language x:Name="Italian" />
</LanguagesCollection>
</myClass.Languages>
<myClass.Countries>
<CountryCollection>
<Country x:Name="UK" Languages="{LanguageSelector 'English'}" />
<Country x:Name="France" Languages="{LanguageSelector 'French'}" />
<Country x:Name="Italy" Languages="{LanguageSelector 'Italian'}" />
<Country x:Name="Switzerland" Languages="{LanguageSelector 'English, French, Italian'}" />
</CountryCollection>
</myClass.Countries>
Run Code Online (Sandbox Code Playgroud)
该语言的每个属性国家目的是与被填充的IEnumerable <语言>含于引用语言中指定的对象LanguageSelector,它是一个自定义标记扩展.
以下是我尝试创建将在此角色中使用的自定义标记扩展:
[ContentProperty("Items")]
[MarkupExtensionReturnType(typeof(IEnumerable<Language>))]
public class LanguageSelector : MarkupExtension
{
public LanguageSelector(string items)
{
Items = items;
}
[ConstructorArgument("items")]
public string Items { get; set; }
public override …
Run Code Online (Sandbox Code Playgroud) 我有一个格式化数字的值转换器(不幸的是我不能使用SP1).它工作正常,直到它获得百分比.
这是一个例子:
<TextBlock Text="{Binding Path=PercentageComplete,
Converter={StaticResource NumberFormatter},
ConverterParameter='0.00 %'}" />
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我Double.ToString
看到一个百分比字符时,它会将该数字乘以100.在我的情况下,该数字已经是一个百分比,不需要转换.
在C#中,这可以通过%
使用单引号转义字符来实现:
(99.99).ToString("0.00 %") // gives -> "9999 %"
(99.99).ToString("0.00 '%") // gives -> "99.99 %"
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不能ConverterParameter
在上面的XAML标记扩展中使用单引号.有没有办法逃避它?我试过加倍单引号并使用反斜杠,但都无法编译.
我试图string.Format
在WPF中提供一个方便的功能,以便各种文本部分可以组合在纯XAML中,而不需要代码隐藏的样板.主要问题是支持函数的参数来自其他嵌套标记扩展(例如Binding
)的情况.
实际上,有一个非常接近我需要的功能:MultiBinding
.不幸的是,它只能接受绑定,但不能接受其他动态类型的内容,比如DynamicResource
s.
如果我的所有数据源都是绑定,我可以像这样使用标记:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource StringFormatConverter}">
<Binding Path="FormatString"/>
<Binding Path="Arg0"/>
<Binding Path="Arg1"/>
<!-- ... -->
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Run Code Online (Sandbox Code Playgroud)
有明显的实施StringFormatConveter
.
我尝试实现自定义标记扩展,以便语法如下:
<TextBlock>
<TextBlock.Text>
<l:StringFormat Format="{Binding FormatString}">
<DynamicResource ResourceKey="ARG0ID"/>
<Binding Path="Arg1"/>
<StaticResource ResourceKey="ARG2ID"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Run Code Online (Sandbox Code Playgroud)
或者只是
<TextBlock Text="{l:StringFormat {Binding FormatString},
arg0={DynamicResource ARG0ID},
arg1={Binding Arg2},
arg2='literal string', ...}"/>
Run Code Online (Sandbox Code Playgroud)
但我坚持执行,ProvideValue(IServiceProvider serviceProvider)
因为参数是另一个标记扩展.
互联网上的大多数例子都是微不足道的:它们要么根本不使用serviceProvider
,要么查询IProvideValueTarget
,它们(大多数)说什么依赖属性是标记扩展的目标.在任何情况下,代码都知道在ProvideValue
呼叫时应该提供的值.但是,ProvideValue
只会调用一次(模板除外,这是一个单独的故事),因此如果实际值不是常数(如同Binding
等),则应使用另一种策略.
我查找了Binding
Reflector中的实现,它的 …
wpf ×7
c# ×5
xaml ×5
.net ×2
binding ×1
collections ×1
design-time ×1
escaping ×1
resharper ×1