さまざまな言語について説明されている多くの隠された機能を次に示します。今、私はXAMLとWPFのいくつかの隠された機能に興味がありますか?
私が見つけたのは、ListViewのヘッダークリックイベントです
<ListView x:Name='lv'
Height="150"
GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">
GridViewColumnHeader.Clickプロパティはリストされていません。
これまでの関連機能の一部:
以下も参照してください:
マルチバインディング (StringFormatと組み合わせて):
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}, {1}">
<Binding Path="LastName" />
<Binding Path="FirstName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
特定のシナリオでバインディングで何が起こっているかをデバッグするための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
3.5sp1はStringFormatをバインディング式に導入しました。
<TextBox Text="{Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}" />
3.5sp1では、バインディングにTargetNullValueが導入されました。これにより、値が入力された場合、バインドされたプロパティがNullに設定され、プロパティがNullの場合、この値が表示されます。
<TextBox Text="{Binding Total, TargetNullValue=$0.00}" />
ラベルに表示するには長すぎる文字列を取得する場合があります。この場合、TextTrimming
のTextBlock
プロパティを使用して、楕円を表示できます。
<TextBlock
Name="sampleTextBlock"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap"/>
<Window.Resources>
<ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
</Window.Resources>
X:TypeArgumentsを使用したXAMLのジェネリック
XAMLでObservableCollectionを使用する場合は、XAMLで宣言できないため、ObservableCollectionから派生する型を作成する必要があります。 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 />
無効なコントロールにツールチップを表示する
Wpfでは、コントロールが無効な状態の場合、コントロールにツールチップを表示できます。
例えば
<Button Content="Disabled Button" ToolTipService.ShowOnDisabled="True" IsEnabled="False" ToolTip="This is a disabled button"/>
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>
マークアップ拡張機能と添付プロパティは私のお気に入りの機能であり、非常にエレガントな方法で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
Ortusが言及したイベント)
実際には隠された機能ではありませんが、WPF/XAMLでは Bea Stollnitz および Josh Smith が得られます。 WPF/XAMLプログラミングのクイーンとキング。
XAMLでプラス記号(+
)。たとえば、このクラスがある場合:
public class SomeClass
{
public enum SomeEnum
{
SomeValue
};
}
次の構文を使用して、XAMLでSomeValue
を参照できます。
{x:Static local:SomeClass+SomeEnum.SomeValue}
この構文は MSDNには記載されていません であり、公式にはサポートされていません。誰か それについて尋ねられた MSDNフォーラムで、VS2010のWPFデザイナーを壊しているようです。 Microsoft Connectでは 報告済み になっています。
グリッドサイズの共有( here's 良い例)。要するに、異なるグリッド間でも、グリッドの列と行のサイズを共有することができます。これは、データをその場で編集する必要なしに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での静的ファクトリメソッドの使用
パブリックコンストラクターではなく静的ファクトリーメソッドを持つ型がある場合、XAML 2006のコードでその型を作成する必要がありました。XAML2009では、x:FactoryMethodx:Arguments属性を使用して引数値を渡すことができます。
<!-- XAML 2006 -->
Guid id = Guid.NewGuid();
<!-- XAML 2009 -->
<Guid x:FactoryMethod="Guid.NewGuid" />
あまり明確ではない別のことは、テキストのみを含むために使用されるいくつかのプロパティのコンテンツです。 GUI要素のプロパティがObject型の場合、テキストを設定するだけでなく、一連のコントロールを含む必要なパネルを追加できる可能性が非常に高くなります。
この例はMenuItemで、Header
プロパティ(通常はテキストのみを含む)には、パネルコントロールにラップされた一連のgui要素(または、必要な場合は1つの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>
XAMLコンバーター
以下のリストは、異なる形式をXAMLに、またはその逆に変換するためにWPFコミュニティによって開発されたコンバーターを示しています。
Adobe Illustrator XAMLエクスポートプラグイン
<Border Background="{DynamicResource {x:Static SystemColors.InactiveBorderBrushKey}}"/>
組み込み型
今日、stringやdoubleなどの単純なタイプのオブジェクトをリソースディクショナリに追加する場合、必要なclr-namespacesを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/>
{x:Reference}を使用した簡単なオブジェクト参照
今日オブジェクト参照を作成する場合は、データバインディングを行い、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" />
任意の辞書キーのサポート
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>
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));
TextBlockにUIElementを詰め込む機能
これがどれだけ便利かはわかりませんが(隠されていると見なされます)、... 最初にそれに遭遇した :
<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は次のようにレンダリングされます。
INotifyPropertyChangedまたはDependencyPropertiesを使用しないバインディング
here で説明したように、INotifyPropertyChangedを使用せずにプレーンCLRオブジェクトプロパティをバインドすることができ、それはちょうど動作します。
これが フォーラム投稿 です。
見積もり:
[...] WPFのデータバインディングエンジンは、ソースオブジェクトがプレーンCLRオブジェクトであり、INotifyPropertyChangedインターフェイスを実装しない場合、ソースプロパティをラップするPropertyDescriptorインスタンスにデータバインドします。データバインディングエンジンは、PropertyDescriptor.AddValueChanged()メソッドを介してプロパティ変更イベントのサブスクライブを試みます。ターゲットデータバインド要素がプロパティ値を変更すると、データバインディングエンジンはPropertyDescriptor.SetValue()メソッドを呼び出して変更された値をソースプロパティに戻し、同時にValueChangedイベントを発生させて他のサブスクライバーに通知します(この場合、他のサブスクライバーは、ListBox内のTextBlocksになります。
INotifyPropertyChangedを実装する場合は、UIにデータバインドする必要があるプロパティのすべてのセッターで変更通知を実装する責任があります。そうしないと、変更は期待どおりに同期されません。[...]
ここに別の 偉大で詳細な記事 の主題があります。
注これは、bindingを使用する場合にのみ機能します。コードから値を更新した場合、変更は通知されません。 [...]
INotifyPropertyChangedの実装は、かなり面倒な開発作業になる可能性があります。ただし、WPFアプリケーションのランタイムフットプリント(メモリとCPU)に対してその作業を比較検討する必要があります。 INPCを自分で実装すると、ランタイムCPUとメモリが節約されます。
アニメーションのデバッグ
一般的なエラー
次のエラーが表示される場合:不変オブジェクトインスタンスで '(0)。(1)'をアニメーション化できません。次の制限のいずれかに遭遇する可能性があります。