WPF和XAML的隐藏功能?

时间:2009-07-14 11:19:56

标签: wpf xaml hidden-features

以下是针对各种语言讨论的大量隐藏功能。现在我好奇XAML和WPF的一些隐藏功能?

我发现的是ListView的标题点击事件

<ListView x:Name='lv' 
      Height="150" 
      GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">

未列出GridViewColumnHeader.Click属性。

到目前为止的一些相关功能:

另见:

  1. Hidden features of C#
  2. Hidden features of Python
  3. Hidden features of ASP.NET
  4. Hidden features of Perl
  5. Hidden features of Java
  6. Hidden features of VB.NET
  7. Hidden features of PHP
  8. Hidden features of Ruby
  9. Hidden features of C
  10. And So On........

25 个答案:

答案 0 :(得分:87)

Multibinding(与StringFormat结合使用):

<TextBlock>
  <TextBlock.Text>
    <MultiBinding StringFormat="{}{0}, {1}">
      <Binding Path="LastName" />
      <Binding Path="FirstName" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

答案 1 :(得分:58)

还有PresentationTraceSources.TraceLevel技巧来调试任何特定场景中绑定的内容。您所要做的就是在WindowsBase程序集中引用System.Diagnostics名称空间

xmlns:sd="clr-namespace:System.Diagnostics;assembly=WindowsBase"

然后在绑定表达式中添加以下内容:

<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 

答案 2 :(得分:44)

3.5sp1将TargetNullValue引入绑定。如果输入值,这将绑定属性设置为Null,如果属性为Null,它将显示该值。

<TextBox Text="{Binding Total, TargetNullValue=$0.00}" />

答案 3 :(得分:44)

3.5sp1将StringFormat引入绑定表达式,例如

<TextBox Text="{Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}" />

答案 4 :(得分:29)

有时你得到的字符串太长而无法在标签上显示。在这种情况下,我们可以使用TextTrimming TextBlock 属性来显示省略号

<TextBlock 
  Name="sampleTextBlock" 
  TextTrimming="WordEllipsis" 
  TextWrapping="NoWrap"/>

MSDN Link

答案 5 :(得分:27)

将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>

答案 6 :(得分:21)

XAML中的泛型x:TypeArguments

如果要在XAML中使用ObservableCollection,则需要创建一个派生自ObservableCollection的类型,因为您无法在XAML中声明它。使用XAML 2009,您可以使用x:TypeArguments属性来定义泛型类型。

<!-- 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 />

答案 7 :(得分:19)

在已禁用的控件上显示工具提示

Wpf允许在控件上显示工具提示,如果它处于禁用状态。

例如

<Button Content="Disabled Button" ToolTipService.ShowOnDisabled="True" IsEnabled="False" ToolTip="This is a disabled button"/> 

答案 8 :(得分:19)

使用带有x:Arguments的非默认构造函数

在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>

答案 9 :(得分:18)

不是真正隐藏的功能,但使用WPF / XAML,您获得Bea StollnitzJosh Smith。女王和WPF / XAML编程之王。

答案 10 :(得分:18)

标记扩展和附加属性是我最喜欢的功能,它们使您能够以非常优雅的方式扩展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的来源(顺便说一句,它使用Ortus提到的GridViewColumnHeader.Click事件)

答案 11 :(得分:15)

您可以使用加号(+)在XAML中引用嵌套类型。例如,如果我们有这个类:

public class SomeClass
{
    public enum SomeEnum
    {
        SomeValue
    };
}

我们可以使用以下语法在XAML中引用SomeValue

{x:Static local:SomeClass+SomeEnum.SomeValue}

此语法为not documented on MSDN,并且不受官方支持。在MSDN论坛上有人asked about it,显然它打破了VS2010的WPF Designer。它在Microsoft Connect上有been reported

答案 12 :(得分:14)

网格大小共享(here's一个很好的例子)。简而言之,即使跨越不同的网格,您也可以将网格列和行共享大小。对于那些使用DataGrids而不需要编辑数据的人来说,这将是非常宝贵的。

答案 13 :(得分:11)

<强> PriorityBinding 即可。允许您以“先到先得”的顺序使用异步绑定:

<TextBlock.Text>
      <PriorityBinding FallbackValue="defaultvalue">
        <Binding Path="SlowestDP" IsAsync="True"/>
        <Binding Path="SlowerDP" IsAsync="True"/>
        <Binding Path="FastDP" />
      </PriorityBinding>
</TextBlock.Text>

答案 14 :(得分:10)

使用静态工厂方法x:FactoryMethod

如果您的类型没有公共构造函数但是静态工厂方法,则必须在XAML 2006中的代码中创建该类型。使用XAML 2009,您可以使用x:FactoryMethodx:Arguments属性来传递参数值。 / p>

<!-- XAML 2006 -->
Guid id = Guid.NewGuid();

<!-- XAML 2009 -->
<Guid x:FactoryMethod="Guid.NewGuid" />

答案 15 :(得分:7)

答案 16 :(得分:7)

高级“标题”属性

另一件不太清楚的事情是我们习惯只包含文本的一些属性的内容。如果GUI元素的属性是Object类型,则很可能您可以添加包含一组控件的需要的面板,而不仅仅是设置文本。

这样的一个示例是MenuItem,其中Header属性(通常只包含文本)可以包含一组包含在面板控件中的gui元素(如果只需要一个,则只包含一个gui元素)

还要注意MenuItem上的Icon属性。这通常包含一个Image元素,但这也可以包含任何东西!

<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>

答案 17 :(得分:6)

使用{x:参考}的简单对象引用

如果要在今天创建对象引用,则需要进行数据绑定并使用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" />

答案 18 :(得分:6)

内置类型

如果要在今天的资源字典中添加简单类型的对象(如string或double),则需要将所需的clr-namespace映射到XML名称空间。在XAML 2009中,我们提供了许多XAML语言中包含的简单类型。

<!-- XAML 2006 -->
<sys:String xmlns:sys="clr-namespace:System;assembly=mscorlib >Test</sys:String>

<!-- XAML 2009 -->
<x:String>Test</x:String>

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/> 

答案 19 :(得分:6)

系统颜色用法

<Border Background="{DynamicResource {x:Static SystemColors.InactiveBorderBrushKey}}"/>

答案 20 :(得分:3)

支持任意字典键

在XAML 2006中,所有显式x:Key值都被视为字符串。在XAML 2009中,您可以通过在ElementSyntax中编写密钥来定义您喜欢的任何类型的密钥。

<!-- 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>

答案 21 :(得分:2)

按代码设置ValidationError

BindingExpression中的ValidatioRule仅在绑定的目标端发生更改时触发。如果您想通过代码设置验证错误,可以使用以下代码段。

设置验证错误

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.ClearInvalid(textBox.GetBindingExpression(TextBox.TextProperty));

答案 22 :(得分:2)

将UIElement加入TextBlock的能力

我不知道它有多么有用(虽然它有资格隐藏)这是......但是当我first ran into it时它确实让我措手不及:

<Grid x:Name="LayoutRoot">
    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid>
            <Rectangle Fill="AliceBlue" Width="25" Height="25"/>
        </Grid>
    </TextBlock>
</Grid>

你可以说下面的xaml可能很有用(即在某些文本的末尾放置一个图形):

<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 Z M 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呈现如下:

Hello World

答案 23 :(得分:1)

调试动画

常见错误

如果收到以下错误:无法在不可变对象实例上设置'(0)。(1)'的动画。可能是您遇到以下限制之一:

  • 您在不设置本地值的情况下为依赖项属性设置动画
  • 您正在为依赖项属性设置动画,该属性的当前值是在未合并到资源字典中的另一个程序集中定义的。
  • 您正在为当前数据绑定的值设置动画

答案 24 :(得分:1)

没有INotifyPropertyChanged或DependencyProperties的绑定

正如所讨论的here,您可以绑定一个没有INotifyPropertyChanged的普通CLR对象属性,它将正常工作

我指的是the Forumpost

引用:

  

[...] WPF的数据绑定引擎将数据绑定到PropertyDescriptor实例,如果源对象是普通的CLR对象并且未实现INotifyPropertyChanged接口,则该实例将包装source属性。数据绑定引擎将尝试通过PropertyDescriptor.AddValueChanged()方法订阅属性更改事件。当目标数据绑定元素更改属性值时,数据绑定引擎将调用PropertyDescriptor.SetValue()方法将更改后的值传回源属性,并且它将同时引发ValueChanged事件以通知其他订阅者(在本例中,其他订阅者将是ListBox中的TextBlock。

     

如果您正在实施INotifyPropertyChanged,那么您完全有责任在需要绑定到UI的数据的每个属性集中实现更改通知。否则,更改将不会像您期望的那样同步。[...]

这是关于这个主题的另一个great and detailed article

  

注意仅在使用绑定时才有效。如果您从代码更新值,则不会通知更改。 [...]

     

实现INotifyPropertyChanged可能是一项繁琐的开发工作。但是,您需要权衡WPF应用程序的运行时占用空间(内存和CPU)。 自己实现INPC将节省运行时CPU和内存