4

TemplateBindingこの特定のケースで失敗するように見えるのはなぜですか?

基本的な拡張ボタンを使用します。

public class IconButton : Button
{
    public ImageSource Icon
    {
        get { return (ImageSource)GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }
    public static readonly DependencyProperty ImageProperty =
        DependencyProperty.Register("Icon", typeof(ImageSource), typeof(IconButton), new PropertyMetadata(null));

    public IconButton()
    {
        DefaultStyleKey = typeof(IconButton);
    }
}

コントロール テンプレートは、次を使用してアイコンを表示しますOpacityMask

<Style TargetType="controls:IconButton">
    <Setter Property="Width" Value="30" />
    <Setter Property="Height" Value="30" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:IconButton">
                <Grid>
                    <Rectangle Fill="{StaticResource PhoneForegroundBrush}"
                               Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                        <Rectangle.OpacityMask>
                            <ImageBrush ImageSource="{TemplateBinding Icon}" />
                        </Rectangle.OpacityMask>
                    </Rectangle>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

これは黙って失敗します。コントロールは塗りつぶされた四角形として表示されます。の代わりに通常の画像を使用するとImageBrush、バインディングは成功します。

            <ControlTemplate TargetType="controls:IconButton">
                <Grid>
                    <Image Source="{TemplateBinding Icon}" />
                </Grid>
            </ControlTemplate>

画像のソース パスをハードコードした場合も正しく動作します。

            <ControlTemplate TargetType="controls:IconButton">
                <Grid>
                    <Rectangle Fill="{StaticResource PhoneForegroundBrush}"
                               Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                        <Rectangle.OpacityMask>
                            <ImageBrush ImageSource="/Images/appbar.next.rest.png" />
                        </Rectangle.OpacityMask>
                    </Rectangle>
                </Grid>
            </ControlTemplate>

では、なぜTemplateBindingの中で失敗するのImageBrushでしょうか?


アップデート

演繹的に (そして Chris からの回答のおかげで)、考えられる要因は次のとおりです。

点がどのようにつながっているかはまだわかりませんが...

4

2 に答える 2

1

興味深いことに、私はあなたの例からその動作を再現することができました。完全にはわかりませんが、何が起こっているのか理解できると思います.

この質問への回答に基づいて: WPF TemplateBinding vs RelativeSource TemplatedParent 2 つのメソッドはほぼ同じことを達成しますが、いくつかの重要な動作が異なるようです。Miroslav Nedyalkov によって言及されている最も関連性の高いもの -

「TemplateBindings は値の変換を許可しません。Converter を渡すことを許可せず、たとえば int を文字列に自動的に変換しません (これは Binding では正常です)。」

2番目のケースでは、バインディングは組み込みのWPFコンバーターを使用して、バインドされたstring/URIを anに変換すると思いますImageSource( an を指定するときの通常の動作ImageSource- 通常、バインディングコンバーターを指定する必要がないのはそのためです)。

最初のケースでは、デフォルト値の変換が得られないため、マスクは表示されません。コンバーターが指定されている場合に機能するかどうかを確認するのは興味深いことです。

ImageBrush編集: から継承しないことによるいくつかの追加の複雑さがあるように見えますFrameworkElement: DependencyProperty を使用して ImageBrush をテンプレートにバインドします

于 2014-03-02T23:00:24.430 に答える