如何在元素后面实现代码的DataBinding?

时间:2012-02-27 04:08:22

标签: wpf data-binding user-controls custom-controls

我有以下场景:我正在创建一个纸牌游戏,作为其中的一部分,我想创建一个UserControl,使界面编程更容易和更好。我正在创建以下用户控件:

的.cs

public partial class ChimeraUserControl : UserControl
{   
    private ChimeraViewModel Chimera { get; set; }

    public ChimeraUserControl(Chimera chimera)
    {
        this.Chimera = new ChimeraViewModel(chimera);
        InitializeComponent();
    }
}

我希望能够做两件事:使用此用户控件时,能够通过绑定发送Chimera,还可以将所有文本和其他元素绑定到此{ {1}}。我搜索了很多,但没有发现任何令我满意的事情。

你们有什么想法?

我已经尝试过阅读:

http://dev-for-fun.blogspot.com/2008/06/wpf-example-create-usercontrol-and.html

Binding from View-Model to View-Model of a child User Control in Silverlight? 2 sources - 1 target

还有很多其他页面,但没有一个看起来很直接,而且通过黑客攻击代码,我找不到问题的解决方案。

2 个答案:

答案 0 :(得分:4)

首先,将Chimera设为Dependency Property,以便它可以参与绑定系统

public static readonly DependencyProperty ChimeraProperty = 
    DependencyProperty.Register("Chimera ", typeof(ChimeraViewModel), 
    typeof(ChimeraUserControl), new FrameworkPropertyMetadata(null));

public ChimeraViewModel Chimera 
{
    get { return (ChimeraViewModel)GetValue(ChimeraProperty ); }
    set { SetValue(ChimeraProperty, value); }
}

其次,您可以通过ChimeriaRelativeSource绑定

引用您的ElementName媒体资源
<UserControl x:Name="ChimeraViewRoot" ... >

    <StackPanel>
        <!-- ElementName Binding -->
        <TextBlock Text="{Binding ElementName=ChimeraViewRoot, Path=Chimeria.Name}" />

        <!-- RelativeSource Binding -->
        <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ChimeraView}}, Path=Chimeria.Name}" />

    </StackPanel>
</UserControl>

您也可以将DataContext内的控件的UserControl设置为Chimera属性,以使您的绑定语法更清晰

<UserControl x:Name="ChimeraViewRoot" ... >
    <StackPanel DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ChimeraView}}, Path=Chimeria}" >

        <TextBlock Text="{Binding Name}" />
        <TextBlock Text="{Binding Description}" />

    </StackPanel>
</UserControl>

我通常不建议在UserControl.DataContext中定义UserControl,因为该值应该从UserControl的任何用途传入。当您试图弄清楚特定UserControl无法与预期UserControl一起使用时,DataContext内部设置可能会引起混淆。


当我创建一个应该与特定ViewModel一起使用的UserControl时,我更喜欢在应用程序中设置DataTemplate,以便我{{1}的所有实例使用我的自定义ViewModel绘制。这意味着我假设UserControl始终是特定的UserControl.DataContext类型

ViewModel

每当Visual Tree遇到<DataTemplate DataType="{x:Type local:ChimeriaViewModel}"> <local:ChimeriaView /> <!-- DataContext will always be ChimeriaViewModel --> </DataTemplate> 类型的对象时,这将隐式使用ChimeriaView

例如,以下内容将呈现ChimeriaViewMmodel填充StackPanel个对象

ChimeriaView

或者为了显示单个对象,我通常会使用类似<ItemsControl ItemsSource="{Binding MyListOfChimeriaViewModels}" />

的内容
ContentControl

此外,通过知道<!-- Will get drawn using ChimeriaView due to DataTemplate defined above --> <ContentControl Content="{Binding MyChimeriaViewModelProperty}" /> 的{​​{1}}将成为DataContext类型的对象,我将完全摆脱ChimeriaView

ChimeriaViewModel

答案 1 :(得分:0)

我可以根据你的追求从我能理解的事情中建议。

  1. 您应该将其设置为Custom控件而不是UserControl。

      

    请查看以下链接以获取帮助 -

         

    Control Authoring Overview

         

    http://www.codeproject.com/Articles/49802/Create-a-WPF-Custom-Control-Part-2

  2.   
  3. Chimera成为DependencyProperty以支持Binding(如您添加及上述文章的SO链接中所述)。
  4.