wpfにおけるxamlのタイプ変換器とタグ拡張


詳細
この記事ではwpfコントロール属性のタイプ変換器について説明します

タイプコンバータ


 
タイプ変換器はasp.Netコントロールでは既に使用するが、wpfのインタフェースはxamlからなるので、ラベルの便利さにもタイプ変換器が必要である.両者の応用は非常に似ている.
Marginプロパティをxamlで設定する
<Button Margin="1,2,3,4">Button>

csコード
Button btn = new Button();
btn.Margin = new Thickness(1, 2, 3, 4);

xamlでMarginを設定と、この属性はタイプ変換器を介してThicknessタイプに変換されます.タイプ変換器に関する知識については、ここではあまり紹介しない.xamlのタグ拡張機能について説明する.

タグ拡張


タグ拡張はwpfの応用において非常に広範である.データバインド構文{Binding Path=...}静的リソースリファレンス{StaticResource...}指定データ型{x:Type prefix:typeName Value}
タグ拡張は多くの利点をもたらすが、一般的にxamlの属性値はテキスト文字列形式がタイプ変換器形式でオブジェクトに変換される(タグ化言語にも限界がある).タグ拡張は、属性が静的オブジェクトの参照を参照することができるが、もちろんこれはその機能の一つであり、文法は左右の括弧で区別される({}).

左上右下の問題


ここでは、タイプ変換器ではできない問題を比較します.
皆さんはwpfやsilverlightを習ったばかりの頃、Marginのプロパティを設定するとき、四辺の順序、すなわち左上右下、以下のblendのプロパティエディタを忘れがちだと思います.
考えを変えて、Marginの左上右下の順序を変えたいならだめです.これはタイプ変換器なので、この順序は決まっています.タグで拡張すると次のような文法{Margin Top=76,Left=76,Right=168,Bottom=0}があると仮定することができる.主な問題はタグ拡張が属性値を記録できることであり、タイプ変換器はテキスト文字列でしか表現できない.1つの複雑な属性のxamlでの表現方法の2つの方法はいずれも可能で、タグの拡張は1つの多くの選択を提供した.応用によって決まる.もちろんタイプ変換器がない場合、xamlもこのような書き方を許可する.相対的に少し複雑で、すべては簡略化のためだ.
<Button>
    <Button.Margin>
        <Thickness Left="0" Top="0" Right="0" Bottom="0">Thickness>
    Button.Margin>
Button>

 
<Button Margin="{Margin Top=0,Left=0,Right=0,Bottom=0}" />
<Button Margin="0,0,0,0" />

上の3つの方法を比较して、最后の1つが最も简単であることを肯定して、记忆のよくないのに対しても第2の种类を试みることができて、実は第1のマークの拡张もあなたが対象の属性を覚える必要があって、万一大文字と小文字の间违いがあれば面倒で、第1の种类、コードの量はまた多すぎて、もしすべて1つの属性を设定してすべてこのようにすれば、コードは多くなります.だからそれぞれメリットがあります.

カスタムタグ拡張


タグ拡張自体は設計時とは関係ないが、タイプ変換器は設計時に必要な機能であり、両者に類似点があるため、ここで紹介する.
カスタムタグ拡張の方法について説明します
(1)派生システムを定義.Windows.Markup.ProvideValueメソッドの書き換えを要求するMarkupExtensionのクラス
namespace WPF.Controls
{
    public class ThicknessExtension : MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            throw new NotImplementedException();
        }
    }
}

(2)xmlネーミングスペースに関連して、プログラムセットプロジェクトのAssemblyInfoにメタデータを追加し、XmlnsDefinitionメタデータはネーミングスペースの統一を助けることができる.これにより、wpf内蔵コントロール(多くのコントロールが異なるネーミングスペースの下にある)を簡単に使用することができるため、XmlnsPrefixの役割はaspのようになる.Net内蔵コントロールはaspで始まるように
[assembly: XmlnsDefinition("http://wpf.controls", "WPF.Controls")]
[assembly: XmlnsPrefix("http://wpf.controls", "ext")]
ProvideValueメソッドを
public override object ProvideValue(IServiceProvider serviceProvider)
{
    return new Thickness();
}

次にxamlでこの拡張タグを使用します
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ext="http://wpf.controls"
    Title="Window1" Height="100" Width="200">
    <Grid>
        <Button Margin="{ext:Thickness}" Content="Hello" />
    Grid>
Window>

上記のコードは正常に実行できます.パラメータを渡すために拡張タグに属性を追加する必要があります.
(3)属性を追加する.xamlに追加されたオブジェクトは、デフォルトのコンストラクション関数で入力され、MarkupExtensionReturnTypeでタグ拡張が返されるセキュリティタイプを指定できます.
[MarkupExtensionReturnType(typeof(Thickness))]
public class ThicknessExtension : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return new Thickness(Left,Top,Right,Bottom);
    }

    public ThicknessExtension()
    {
    }

    public double Bottom { get; set; }
    public double Left { get; set; }
    public double Right { get; set; }
    public double Top { get; set; }
}

今すぐご利用いただけます
<Button x:Name="demo" Margin="{ext:Thickness Left=10,Bottom=10,Right=10,Top=30}"
        Content="Hello">
    
Button>