3

カスタムCanvasを作成して使用しようとしています。XAML(MyCanvas.xaml)は次のとおりです。

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:Core="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Namespace="clr-namespace:MyNamepace" xmlns:Properties="clr-namespace:MyNamepace.Properties" Core:Class="MyNamepace.MyCanvas">
    <Canvas.Resources>
        <Namespace:ImagesConverter Core:Key="ImagesConverter"/>
    </Canvas.Resources>
    <Image Source="{Binding Source={Core:Static Properties:Resources.Background}, Converter={StaticResource ImagesConverter}}" Stretch="Fill"/>
</Canvas>

コード宣言(MyCanvas.xaml.cs)は次のとおりです。

public partial class MyCanvas : Canvas

私がそのようにそれを使おうとすると:

<Namespace:MyCanvas Core:Name="Layout" Loaded="OnLoaded">
    <Namespace:MyUserControl Core:Name="Control1" Namespace:MyCanvas.Left="50" MyProperty="50">
        <Namespace:MyCanvas.Top>
            <MultiBinding Converter="{StaticResource MathConverter}" ConverterParameter="(x - y) / 2">
                <Binding ElementName="Layout" Path="ActualHeight"/>
                <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
            </MultiBinding>
        </Namespace:MyCanvas.Top>
    </Namespace:MyUserControl>
    <Namespace:MyUserControl Core:Name="Control2" Namespace:MyCanvas.Left="744" Namespace:MyCanvas.Top="42" MyProperty="150"/>
</Namespace:MyCanvas>

2つの異なるエラーが発生します。

プロパティ「コンテンツ」は一度だけ設定できます。==> Canvasを継承していませんか?!?!?!

メンバー「トップ」が認識されないか、アクセスできません。==>再びCanvasを継承していませんか?!?!?!メンバー「Left」が認識されないか、アクセスできません。==>再びCanvasを継承していませんか?!?!?!

編集:これは私がこれまでに持っているものです...まだ「コンテンツ」がすでに設定されているエラーが発生します!

MyCanvas.xaml

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:Core="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Namespace="clr-namespace:MyNamespace" xmlns:Properties="clr-namespace:MyNamespace.Properties" Core:Class="MyNamespace.MyCanvas">
    <Canvas.Background>
        <ImageBrush ImageSource="{Binding Source={Core:Static Properties:Resources.Background}, Converter={StaticResource ImagesConverter}}" Stretch="Fill"/>
    </Canvas.Background>
    <Canvas.Resources>
        <Namespace:ImagesConverter Core:Key="ImagesConverter"/>
    </Canvas.Resources>
</Canvas>

MyCanvas.xaml.cs

public class MyCanvas : Canvas
{
    // ...
}

MainWindow.xaml

<Namespace:MyCanvas Core:Name="MyCanvas" Loaded="OnLoaded">
    <Namespace:MyUserControl ...
    <Namespace:MyUserControl ...
    <Namespace:MyUserControl ...
</Namespace:MyCanvas>
4

2 に答える 2

4

Leftおよび添付プロパティTopです。つまり、それらはクラスに継承されません。

代わりに使用するユーザー コントロール宣言を変更する必要がありますCanvas.LeftCanvas.Top

<Namespace:MyUserControl Core:Name="Control2" Canvas.Left="744" Canvas.Top="42" 
                         MyProperty="150"/>

コンテンツの問題は、エラー メッセージが示すように、2 回設定したことです。

  1. MyCanvas.xaml設定しますImage
  2. それを使用するときは、ユーザー コントロールに設定します。

ItemsControlこれを修正するには、 toを追加しMyCanvasて、コンテンツを表すコントロールとして宣言する必要があります。

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:Core="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Namespace="clr-namespace:MyNamepace" xmlns:Properties="clr-namespace:MyNamepace.Properties" Core:Class="MyNamepace.MyCanvas">
    <Canvas.Resources>
        <Namespace:ImagesConverter Core:Key="ImagesConverter"/>
    </Canvas.Resources>
    <Image Source="{Binding Source={Core:Static Properties:Resources.Background}, Converter={StaticResource ImagesConverter}}" Stretch="Fill"/>
    <ItemsControl Content="{Binding Path=LocalContent, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Namespace:MyCanvas}}}" />
</Canvas>

クラスファイルで:

[ContentProperty("LocalContent")]
public partial class MyCanvas : Canvas
{
    public static readonly DependencyProperty LocalContentProperty =
        DependencyProperty.Register(
            "LocalContent", 
            typeof(UIElementCollection), 
            typeof(MyCanvas ), 
            new PropertyMetadata(default(UIElementCollection)));
}
于 2013-02-07T13:23:52.827 に答える
4

ダニエルの答えに加えて、WPF が「依存関係プロパティ」および「依存オブジェクト」と呼ばれる概念を導入していることを理解する必要があります。つまり、C# のオブジェクトがプロパティを持つことができるように、WPF の依存関係オブジェクトは依存関係プロパティを持つことができます。これが機能する方法は、C# メソッドとは少し異なります。

依存関係プロパティ (添付プロパティなど) の場合、WPF は、どのオブジェクトがどのプロパティを持つかを示すレコードを含む別のテーブルを管理します。言い換えれば、任意のオブジェクトが任意のプロパティを持つことが可能であることを意味します。WPF は、そのオブジェクトにそのプロパティを与えるテーブルにレコードを追加するだけです。たとえば、Canvas.Left はCanvas によって定義されていますが、任意のコントロールによって実装できます。WPF は依存関係テーブルにレコードを挿入するだけで、画像に Canvas.Left / Canvas.Top プロパティが含まれるようになりました。これは、オブジェクトが特定のクラスから派生したという理由だけでプロパティを持つのではなく、(レコードが追加されたときに) プロパティを持つことを選択するため、メモリ フットプリントがはるかに小さいことを意味します。

これがプログラム的に機能する方法は、DependencyObject.SetValue / GetValue を使用することです (すべての WPF オブジェクトは DependencyObject から派生します: http://miteshsureja.blogspot.com/2011/06/wpf-class-hierarchy.htmlを参照してください- 実際、これを覚えておいてください)これは、WPF が内部でどのように機能するかをよりよく理解するのに役立つためです)。これにより、前述のテーブルにレコードが追加/読み取られます。依存関係プロパティを定義するときは、C# アクセサーが実際にこれらのメソッドにリダイレクトする必要があります。これは、WPF (オブジェクト自体ではなく) がこれらの値を管理する必要があるためです (これが、WPF がデータ バインディングを実行できる方法であり、できないことです。値を管理し、必要に応じて他のオブジェクトにシフトするだけです)。依存関係プロパティの作成例については、http: //msdn.microsoft.com/en-us/library/ms752914.aspxを参照してください。. 依存関係プロパティの背後にある概念は非常に単純ですが、多くの WPF 機能を理解するには、少なくともそれを認識しておく必要があります。

于 2013-02-07T13:36:53.990 に答える