WPFとXAMLの隠された機能?


123

ここでは、さまざまな言語について説明されている非表示の機能が多数あります。XAMLとWPFのいくつかの隠された機能に興味がありますか?

私が見つけたのは、ListViewのヘッダークリックイベントです。

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

GridViewColumnHeader.Clickプロパティは表示されません。

これまでのいくつかの関連機能:

以下も参照してください。

  1. C#の非表示機能
  2. Pythonの隠し機能
  3. ASP.NETの隠し機能
  4. Perlの隠された機能
  5. Javaの隠された機能
  6. VB.NETの非表示機能
  7. PHPの隠された機能
  8. Rubyの隠し機能
  9. Cの隠し機能
  10. 等々........

7
ここmsdn.microsoft.com/en-us/library/…をご覧ください。クリックイベントはButtonBaseから継承されます。あなたが説明しているのは、WPF(msdn.microsoft.com/en-us/library/bb613550.aspx)の非常に強力な概念である添付イベントです。このようにして、グリッド上の100個のボタンと1つのハンドラのみで<Grid Button.Click>を実行できます。
Sorskoot 2009

1
最初は「ああ、またここに行きます」のようでしたが、それから応答で何かを学んだので、それをすべて取り戻します:o:o
Sam Harwell

1
コミュニティWikiである必要があります
tsilb

2
@tsilb私は、このリンクを見て、それがコミュニティのwikiすべきだと思いませんmeta.stackexchange.com/questions/392/...
のPrashant Cholachagudda

回答:


87

マルチバインディングStringFormatと組み合わせて):

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

1
素晴らしい:-) Silverlight 4以前を使用している場合を除きます。v5で指が交差
Simon_Weaver 2010

5
これは素晴らしいですが、私はそれをしないように誘惑されます。文字列を作成する必要がある場合は、それをロジックとしてクラス化し、出力の単体テストを行います。このようなものは、ビューモデルではstring.Format()の方が良い場合があります。
Iainホルダー

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 

4
VisualStudio 2010では、トレース設定のレベルを警告に設定する必要があります!stackoverflow.com/questions/2802662/…を
WaltiD

44

3.5sp1では、バインディングにTargetNullValueが導入されました。これにより、値が入力された場合はバウンドプロパティがNullに設定され、プロパティがNullの場合はこの値が表示されます。

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

44

3.5sp1は、バインディング式にStringFormatを導入しました。

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

私はその機能がどれほど気に入っているかを言葉で表すことはできません。値コンバーターをたくさん並べることが嫌だった。
Rob、

ええ、最も時間を節約できる機能が簡単に追加されました。特にTargetNullValueと組み合わせると、多くの問題が解消されます。
ブライアンアンダーソン、

6
StringFormatを単一引用符で囲むと、コンパイラの警告がいくつか削除されますText={Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}"
Ryan Versaw '14

知っておくと、私はそれらを単に無視することに慣れてきました。
ブライアンアンダーソン、

1
任意のフォーマット文字列が機能することを伝えようとしていました。この場合、国際化バージョンはStringFormat = '{} {0:d}'になると思います。
ブライアンアンダーソン

29

時には、ラベルに表示するには長すぎる文字列を取得します。この場合、のTextTrimmingプロパティを使用してTextBlock楕円を表示できます

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

MSDNリンク


このような場合のツールチップを追加することを検討してください:tranxcoder.wordpress.com/2008/10/12/...
surfen

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>

1
コードを追加しましたが、まだAero効果は追加していません。何か不足していますか?
Elmo

21

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

1
残念ながら、x:TypeArgumentsはルーズなxamlファイルでのみ使用でき、コンパイルされたファイルでは使用できません:(
kevindaub

はい、xamlのみを緩めます:(WPF開発者の大多数にとってXAML2009は役に立たない
Grigory

19

無効なコントロールにツールチップを表示する

Wpfでは、コントロールが無効な状態の場合、コントロールにツールチップを表示できます。

例えば

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

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>


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によって言及されたイベントを使用します


のソースはWinUtil.EnableAeroGlassどこかで入手できますか?
オスカー

はい、しかし私がこれを投稿して以来、大きく変化しました...現在、EnableBlurとGlassFrameMarginsの2つのプロパティがあります。あなたはここにコードを見つけることができます:projets.developpez.com/projects/dvp-net/repository/entry/trunk/...
トーマス・レベスク

15

プラス記号(+)を使用して、XAMLでネストされた型を参照できます。たとえば、次のクラスがあるとします。

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

SomeValue次の構文を使用してXAMLで参照できます。

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

この構文はMSDN記載されておらず、公式にはサポートされていません。誰か MSDNフォーラムでそれについて質問しました、そしてそれはどうやらそれはVS2010のWPFデザイナーを壊します。Microsoft Connectで報告されてます。


14

グリッドサイズの共有(ここだ良い例が)。要するに、グリッドが異なるグリッド間でも、グリッドの列と行でサイズを共有することができます。これは、データを編集せずにDataGridを使用しているすべての人にとって非常に貴重です。


11

PriorityBinding。「先着順」の順序でasynバインディングを使用できるようにします。

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

10

x:FactoryMethodでの静的ファクトリメソッドの使用

パブリックコンストラクターはないが静的なファクトリメソッドを持つ型がある場合、XAML 2006のコードでその型を作成する必要がありました。XAML2009では、x:FactoryMethodx:Arguments属性を使用して引数の値を渡すことができます。

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

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

7

高度な「キャプション」プロパティ

あまり明確ではないもう1つのことは、テキストのみを含むために使用されているいくつかのプロパティの内容です。GUI要素のプロパティがObject型である場合、テキストを設定するだけでなく、一連のコントロールを含む必要なパネルを追加できる可能性が高くなります。

この例はMenuItemで、Headerプロパティ(通常はテキストのみを含む)には、パネルコントロールでラップされた一連のgui要素(または、必要な場合は1つのgui要素)を含めることができます。

IconMenuItem のプロパティにも注意してください。通常、これには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>

7

また、非常に便利です。GridLengthConverter、BooleanToVisibilityConverter、AlternationConverterはすべてSystem.Windows.Controlsにあります
MaciekŚwiszczowski

6

組み込み型

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

これは、WPFを使用してXAMLを処理する場合は機能しません。msdn.microsoft.com/en-us/library/ee792007.aspx
scobi

6

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

x:ReferenceはXAML 2009言語機能ですが、コンパイルされたXAMLでも機能するいくつかのシナリオがあることに注意してください。ただし、すべての場所で機能するわけではなく、XAMLデザイナービューが壊れる可能性があります。
Mike Strobel、2011

1
@MikeStrobel:ほぼどこでも機能しますが、デザイナーが壊れることを気にする必要はありませんでした。
HB

6

システムカラーの使用

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

3
アプリケーションの実行中にユーザーがシステムの色を変更できるため、DynamicResourceとして指定することは重要です。
M.ダドリー

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>

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

2

UIElementをTextBlockに詰め込む機能

私はこれがどのように役に立つ(かかわら隠されたとして、それは資格)知らない...しかし、とき、私にはわから油断私を捕まえ、それへの第1のRAN

<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は次のようにレンダリングされます。

こんにちは世界


1

アニメーションのデバッグ

一般的なエラー

次のエラーが発生した場合:不変オブジェクトインスタンスで「(0)。(1)」をアニメーション化できません。次の制限の1つに直面している可能性があります。

  • ローカル値を設定せずに依存関係プロパティをアニメーション化している
  • 現在の値がリソースディクショナリにマージされていない別のアセンブリで定義されている依存関係プロパティをアニメーション化しています。
  • 現在データバインドされている値をアニメーション化しています

1

INotifyPropertyChangedまたはDependencyPropertiesなしのバインド

説明したように、ここであなたはINotifyPropertyChangedのなしでプレーンなCLRオブジェクトのプロパティをバインドすることができ、それがされますちょうど働きます

これが私が言及しているフォーラムポストです。

見積もり:

[...]ソースオブジェクトがプレーンCLRオブジェクトであり、INotifyPropertyChangedインターフェイスを実装していない場合、WPFのデータバインディングエンジンは、ソースプロパティをラップするPropertyDescriptorインスタンスにデータバインドします。そして、データバインディングエンジンは、PropertyDescriptor.AddValueChanged()メソッドを介してプロパティ変更イベントにサブスクライブしようとします。また、ターゲットデータバインド要素がプロパティ値を変更すると、データバインディングエンジンはPropertyDescriptor.SetValue()メソッドを呼び出して変更された値をソースプロパティに転送し、同時にValueChangedイベントを発生させて他のサブスクライバーに通知します(このインスタンスでは、他のサブスクライバーは、ListBox内のTextBlockです。

また、INotifyPropertyChangedを実装する場合は、UIにデータバインドする必要があるプロパティのすべてのセッターに変更通知を実装する必要があります。そうしないと、変更は期待どおりに同期されません。[...]

これは、この主題に関するもう1つのすばらしい詳細な記事です。

これはバインディングを使用する場合にのみ機能することに注意してください。コードから値を更新しても、変更は通知されません。[...]

INotifyPropertyChangedの実装は、かなり面倒な開発作業になる可能性があります。ただし、その作業をWPFアプリケーションのランタイムフットプリント(メモリとCPU)と比較検討する必要があります。INPCを自分で実装すると、ランタイムCPUとメモリを節約できます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.