WPF和XAML的隐藏function?
以下是针对各种语言讨论的大量隐藏function。 现在我很好奇XAML和WPF的一些隐藏function吗?
我发现一个ListView的标题点击事件
<ListView x:Name='lv' Height="150" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">
GridViewColumnHeader.Click属性未列出。
以下是一些相关的function:
-
多重绑定结合StringFormat
-
TargetNullValue绑定
-
TextTrimming属性
-
标记扩展
-
将Aero效果添加到窗口
-
高级“标题”属性
-
XAML转换器
也可以看看:
- C#隐藏的function
- Python的隐藏function
- ASP.NET的隐藏function
- Perl的隐藏function
- Java的隐藏function
- VB.NET的隐藏function
- PHP的隐藏function
- Ruby的隐藏function
- C的隐藏function
- 等等……..
多重绑定 (与StringFormat组合):
<TextBlock> <TextBlock.Text> <MultiBinding StringFormat="{}{0}, {1}"> <Binding Path="LastName" /> <Binding Path="FirstName" /> </MultiBinding> </TextBlock.Text> </TextBlock>
还有PresentationTraceSources.TraceLevel技巧来debugging在任何特定情况下绑定的情况。 你所要做的就是在WindowsBase程序集中引用System.Diagnostics命名空间
xmlns:sd="clr-namespace:System.Diagnostics;assembly=WindowsBase"
然后将以下内容添加到绑定expression式中:
<TextBlock Text="{Binding Message, sd:PresentationTraceSources.TraceLevel=High}" />
日志将如下所示:
System.Windows.Data Warning: 52 : Created BindingExpression (hash=5923895) for Binding (hash=7588182) System.Windows.Data Warning: 54 : Path: 'Message' System.Windows.Data Warning: 56 : BindingExpression (hash=5923895): Default mode resolved to OneWay System.Windows.Data Warning: 57 : BindingExpression (hash=5923895): Default update trigger resolved to PropertyChanged System.Windows.Data Warning: 58 : BindingExpression (hash=5923895): Attach to System.Windows.Controls.TextBlock.Text (hash=65248697) System.Windows.Data Warning: 63 : BindingExpression (hash=5923895): Resolving source
3.5sp1引入了TargetNullValue绑定。 这将设置绑定属性为空,如果input的值,如果你的属性是空的,它会显示这个值。
<TextBox Text="{Binding Total, TargetNullValue=$0.00}" />
3.5sp1引入了StringFormat到绑定expression式中,例如
<TextBox Text="{Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}" />
有时你会得到太长的string以显示在标签上。 在这种情况下,我们可以利用TextBlock
的TextTrimming
属性来显示省略号
<TextBlock Name="sampleTextBlock" TextTrimming="WordEllipsis" TextWrapping="NoWrap"/>
MSDN链接
将Aero效果添加到窗口
<Window.Resources> <ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" /> </Window.Resources>
XAML中generics与x:TypeArguments
如果你想在XAML中使用ObservableCollection,你需要创build一个派生自ObservableCollection的types,因为你不能在XAML中声明它。 使用XAML 2009,您可以使用x:TypeArguments属性来定义genericstypes。
<!-- XAML 2006 --> class EmployeeCollection : ObservableCollection<Employee> { } <l:EmployeeCollection> <l:Employee FirstName="John" Name="Doe" /> <l:Employee FirstName="Tim" Name="Smith" /> </lEmployeeCollection> <!-- XAML 2009 --> <ObservableCollection x:TypeArguments="Employee"> <l:Employee FirstName="John" Name="Doe" /> <l:Employee FirstName="Tim" Name="Smith" /> </ObservableCollection />
在禁用的控件上显示工具提示
Wpf允许在控件上显示工具提示,如果它处于禁用状态。
例如
<Button Content="Disabled Button" ToolTipService.ShowOnDisabled="True" IsEnabled="False" ToolTip="This is a disabled button"/>
使用带有x:参数的非默认构造函数
在XAML 2006中,对象必须有一个公共的默认构造函数来使用它们。 在XAML 2009中,您可以使用x:Arguments语法传递构造函数参数。
<!-- XAML 2006 --> <DateTime>00:00:00.0000100</DateTime> <!-- XAML 2009 --> <DateTime> <x:Arguments> <x:Int64>100</x:Int64> </x:Arguments> </DateTime>
不是一个隐藏的function,但与WPF / XAML你得到比斯托尔尼茨和乔什史密斯 。 WPF / XAML编程的皇后和国王。
标记扩展和附加属性是我最喜欢的function,它们使您能够以非常优雅的方式扩展XAML“词汇表”。
标记扩展
<!-- Binding to app settings --> <CheckBox IsChecked="{my:SettingBinding MinimizeToTray}">Close to tray</CheckBox> <!-- Fill ItemsControl with the values of an enum --> <ComboBox ItemsSource="{my:EnumValues sys:DaysOfWeek}"/> <!-- Localization --> <TextBlock Text="{my:Localize HelloWorld.Text}"/> <!-- Switch on the result of a binding --> <TextBlock Text="{my:Switch Path=IsGood, ValueIfTrue=Good, ValueIfFalse=Bad}"/>
附加属性
<!-- Sort GridView automatically --> <ListView ItemsSource="{Binding Persons}" IsSynchronizedWithCurrentItem="True" util:GridViewSort.AutoSort="True"> <ListView.View> <GridView> <GridView.Columns> <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" util:GridViewSort.PropertyName="Name"/> <GridViewColumn Header="First name" DisplayMemberBinding="{Binding FirstName}" util:GridViewSort.PropertyName="FirstName"/> <GridViewColumn Header="Date of birth" DisplayMemberBinding="{Binding DateOfBirth}" util:GridViewSort.PropertyName="DateOfBirth"/> </GridView.Columns> </GridView> </ListView.View> </ListView> <!-- Vista Glass effect --> <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:WpfApplication1" Title="Window1" my:WinUtil.EnableAeroGlass="True"> ...
GridViewSort的源代码(顺便说一下,它使用了GridViewColumnHeader.Click
提到的GridViewColumnHeader.Click
事件)
您可以使用加号( +
)在XAML中引用嵌套types。 例如,如果我们有这个类:
public class SomeClass { public enum SomeEnum { SomeValue }; }
我们可以使用下面的语法在XAML中引用SomeValue
:
{x:Static local:SomeClass+SomeEnum.SomeValue}
此语法在MSDN上没有logging ,并且没有官方支持。 有人问在MSDN论坛上,显然它打破了VS2010的WPFdevise器。 已经在Microsoft Connect上报告过。
网格大小共享( 这里是一个很好的例子)。 长话短说,即使在不同的网格中,您也可以拥有网格列和行共享大小。 对于那些使用DataGrid的人来说,这将是非常宝贵的,无需编辑数据。
PriorityBinding 。 允许您以“先到先显示”顺序使用asyn绑定:
<TextBlock.Text> <PriorityBinding FallbackValue="defaultvalue"> <Binding Path="SlowestDP" IsAsync="True"/> <Binding Path="SlowerDP" IsAsync="True"/> <Binding Path="FastDP" /> </PriorityBinding> </TextBlock.Text>
使用x:FactoryMethod的静态工厂方法
如果您的types没有公共构造函数,但使用静态工厂方法,则必须在XAML 2006的代码中创build该types。使用XAML 2009,可以使用x:FactoryMethodx:Arguments属性来传递参数值。
<!-- XAML 2006 --> Guid id = Guid.NewGuid(); <!-- XAML 2009 --> <Guid x:FactoryMethod="Guid.NewGuid" />
高级“标题”属性
另一个不太清楚的是我们习惯的一些属性的内容只包含文本。 如果GUI元素的属性是Objecttypes的,那么很有可能您不需要设置文本,而是添加一个包含一组控件的需求面板。
一个例子是MenuItem,其中Header
属性(通常只包含文本)可以包含一组包含在面板控件中的gui元素(或者只需要一个gui元素)。
还要注意MenuItem上的Icon
属性。 这通常包含一个图像元素,但这也可以包含任何东西!
<MenuItem Name="MyMenuItem" Click="MyMenuItem_Click"> <MenuItem.Icon> <Button Click="Button1_Click">i</Button> </MenuItem.Icon> <MenuItem.Header> <StackPanel Orientation="Horizontal" > <Label>My text</Label> <Button Click="Button2_Click">ClickMe!</Button> </StackPanel> </MenuItem.Header> </MenuItem>
XAML转换器
以下列表显示了由WPF社区开发的将不同格式转换为XAML的转换器,反之亦然。
Adobe Illustrator XAML导出插件
Adobe Photoshop到XAML转换器
搅拌机XAML出口插件
Lightwave XAML导出插件
Visio XAML导出
3D Studio Max到XAML转换器
玛雅到XAML转换器
Flash到XAML转换器
SVG到XAML转换器
WMF / EMF到XAML转换器
内置types
如果要今天将简单types的对象(如string或double)添加到资源字典中,则需要将所需的clr-namespaces映射到XML名称空间。 在XAML 2009中,我们使用了许多包含在XAML语言中的简单types。
<!-- XAML 2006 --> <sys:String xmlns:sys="clr-namespace:System;assembly=mscorlib >Test</sys:String> <!-- XAML 2009 --> <x:String>Test</x:String>
以下types包含在XAML语言中:
<x:Object/> <x:Boolean/> <x:Char/> <x:String/> <x:Decimal/> <x:Single/> <x:Double/> <x:Int16/> <x:Int32/> <x:Int64/> <x:TimeSpan/> <x:Uri/> <x:Byte/> <x:Array/> <x:List/> <x:Dictionary/>
使用{x:Reference}的简单对象引用
如果你今天想创build一个对象引用,你需要做一个数据绑定,并用一个ElementName声明源。 在XAML 2009中,您可以使用新的{x:Reference}标记扩展
<!-- XAML 2006 --> <Label Target="{Binding ElementName=firstName}">FirstName</Label> <TextBox x:Name="firstName" /> <!-- XAML 2009 --> <Label Target="{x:Reference firstName}">FirstName</Label> <TextBox x:Name="firstName" />
系统颜色使用
<Border Background="{DynamicResource {x:Static SystemColors.InactiveBorderBrushKey}}"/>
支持任意字典键
在XAML 2006中,所有显式的x:Key值被视为string。 在XAML 2009中,您可以通过在ElementSyntax中编写密钥来定义任何types的密钥。
<!-- XAML 2006 --> <StreamGeometry x:Key="CheckGeometry">M 0 0 L 12 8 l 9 12 z</StreamGeometry> <!-- XAML 2009 --> <StreamGeometry>M 0 0 L 12 8 l 9 12 z <x:Key><x:Double>10.0</x:Double></x:Key> </StreamGeometry>
按代码设置ValidationError
BindingExpression中的ValidatioRule仅在绑定的目标侧发生变化时触发。 如果你想通过代码设置validation错误,你可以使用下面的代码片段。
设置validation错误
ValidationError validationError = new ValidationError(regexValidationRule, textBox.GetBindingExpression(TextBox.TextProperty)); validationError.ErrorContent = "This is not a valid e-mail address"; Validation.MarkInvalid( textBox.GetBindingExpression(TextBox.TextProperty), validationError);
清除validation错误
Validation.ClearInvalid(textBox.GetBindingExpression(TextBox.TextProperty));
将元素embedded到TextBlock中的能力
我不知道这是多么有用(虽然它可以隐藏起来),但是当我第一次遇到它的时候,它确实让我感到无奈 :
<Grid x:Name="LayoutRoot"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid> <Rectangle Fill="AliceBlue" Width="25" Height="25"/> </Grid> </TextBlock> </Grid>
你可以争辩下面的xaml可能是有用的(即把graphics放在一些文本的末尾):
<Grid> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Hello World"> <TextBlock.Resources> <DrawingBrush x:Key="exclamationPoint" Stretch="Uniform"> <DrawingBrush.Drawing> <DrawingGroup> <DrawingGroup.Children> <GeometryDrawing Brush="#FF375CE2" Geometry="F1 M 7.968,58.164L 0,58.164L 1.914,49.921L 9.882,49.921L 7.968,58.164 ZM 21.796,0L 11.054,42.148L 4.403,42.148L 13.049,0L 21.796,0 Z "/> </DrawingGroup.Children> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> </TextBlock.Resources> <Grid> <Rectangle Width="100" Height="100" Fill="{StaticResource exclamationPoint}"/> </Grid> </TextBlock> </Grid>
上面的xaml呈现如下:
debugginganimation
常见错误
如果出现以下错误:无法在不可变对象实例上设置“(0)。(1)”。 这可能是您遇到以下限制之一:
- 您正在animation一个依赖项属性而不设置本地值
- 您正在为依赖项属性设置animation,该属性的当前值在未合并到资源字典中的另一个程序集中定义。
- 您正在animation一个当前数据绑定的值
绑定没有INotifyPropertyChanged或DependencyProperties
正如这里所讨论的,你可以绑定一个普通的CLR对象属性,而不需要INotifyPropertyChanged,它就可以工作 。
这里是我所指的论坛。
引用:
WPF的数据绑定引擎将数据绑定到PropertyDescriptor实例,如果源对象是普通的CLR对象并且不实现INotifyPropertyChanged接口,该实例将包装源属性。 数据绑定引擎将尝试通过PropertyDescriptor.AddValueChanged()方法来订阅属性已更改的事件。 而当目标数据绑定元素更改属性值时,数据绑定引擎将调用PropertyDescriptor.SetValue()方法将更改的值传回给源属性,同时引发ValueChanged事件以通知其他订户(在此情况下,其他订阅者将是ListBox中的TextBlocks。
如果您正在实施INotifyPropertyChanged,则完全有责任在需要将数据绑定到UI的属性的每个设置器中实施更改通知。 否则,这个改变将不会像你期望的那样同步。
这是另外一篇关于这个主题的伟大而详细的文章 。
注意这只在使用绑定时才起作用 。 如果您更新代码中的值, 则不会通知更改。 […]
实现INotifyPropertyChanged可能是一件乏味的开发工作。 但是,您需要权衡WPF应用程序的运行时间占用空间(内存和CPU)。 自己实现INPC将节省运行时CPU和内存 。