3

コントロールテンプレート:

    <ControlTemplate x:Key="BasicShape2">
    <StackPanel Name="sp">
        <Border Name="bd" CornerRadius="3.5" BorderThickness="1" BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent},Path=DataContext.NodeType, Converter={StaticResource NodeTypeColorConverter}, Mode=OneWay}" Height="32" Padding="1">
            <TextBlock Name="tbName" Grid.Column="1" Text="" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" />
        </Border>
    </StackPanel>
</ControlTemplate>

このテンプレートが適用されるクラス:

    public class MyThumbEx : Thumb
{
    public static readonly DependencyProperty MemberInfoProperty = DependencyProperty.Register("MemberInfo", typeof(FamilyMemberInfo), typeof(MyThumbEx));
    public FamilyMemberInfo MemberInfo
    {
        get { return (FamilyMemberInfo)GetValue(MemberInfoProperty); }
        set { SetValue(MemberInfoProperty, value); }
    }

    public MyThumbEx(ControlTemplate template, FamilyMemberInfo info, Point position)
    {
        this.MemberInfo = info;
        this.DataContext = this.MemberInfo;
        this.Template = template;
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        this.ApplyTextContent();
    }

    public void ApplyTextContent()
    {
        TextBlock tbName = this.Template.FindName("tbName", this) as TextBlock;
        if (tbName != null)
        {
            tbName.Text = this.MemberInfo.Name;
        }
    }
}

初期化してキャンバスに表示します。

        public MainWindow()
    {
        InitializeComponent();
        //
        FamilyMemberInfo mi = new FamilyMemberInfo();
        mi.Name = "someone";
        mi.ID = "id1";
        MyThumbEx te = new MyThumbEx(Application.Current.Resources["BasicShape2"] as ControlTemplate, mi, new Point(0, 0));
        //
        this.cvMain.Children.Add(te);
    }

これらのコードは正常に機能しますが、コントロールテンプレートでは、Path=NodeTypeだけでなくPath=DataContext.NodeTypeを設定する必要があることに注意してください。私はWPFを初めて使用しますが、通常、このテンプレートを使用せずにバインドを行った場合、述語「DataContext」を指定する必要がないことがわかりました。なぜここが必要なのですか?

私が見つけたもう1つのことは、this.DataContext = this.MemberInfoをコメントアウトし、バインディングパスをPath = MemberInfo.NodeTypeに変更しても、コードは正常に機能することです。誰かが私のためにそれを説明できますか?

前もって感謝します!

4

1 に答える 1

3

DataContextを手動で変更しない場合、すべての子は自動的にその親のDataContextを持ちます。したがって、ウィンドウにDataContextとしてのViewModelがある場合、そのすべてのコントロールは、を介してViewModelsプロパティにアクセスできます{Binding Path=Property}

ただし、ControlTemplateの場合、DataContextが親から子にカスケードする通常の一般的なフローはここでは適用されません。Property="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.Property}"したがって、最初にまたはを介してDataContextを設定する必要がありますDataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}" Property="{Binding Path=Property}"

2番目のポイント:ControlTemplateは、含まれている要素のコードビハインドをDataContextとして自動的に使用するため、DataContextを設定せずにコードビハインドプロパティを使用できますが、これについて100%確信はありません。

于 2012-10-19T05:09:25.360 に答える