none
【自定义控件】自定义控件如何进行数据绑定? RRS feed

  • 问题

  • 下面的是摘自 博客园 UAP 的部分代码片段:

    <Style TargetType="local:PostControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:PostControl">
                        <Border BorderThickness="0,0,0,1" BorderBrush="{ThemeResource CNBlogsLineColor}">
                            <Grid Margin="15">
                                <Grid.RowDefinitions>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <TextBlock x:Name="tb_Title" Grid.Row="0" Text="{Binding Title}" Style="{StaticResource PostTitleFont}"/>
                                <Grid Grid.Row="1" Margin="0,5,0,0">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <local:AuthorControl Grid.Column ="0" Visibility="{TemplateBinding AuthorVisible}" NameFontSize="20" NameColor="{ThemeResource CNBlogsAttributionColor}" AvatarHeight="25" Margin="0,0,10,0" />
                                    <TextBlock Grid.Column="1" Text="{Binding PublishTime, Converter={StaticResource TimeCountDownConverter}}" Style="{StaticResource PublishTimeFont}" VerticalAlignment="Center"/>
                                    <TextBlock x:Name="tb_Status" Grid.Column="2" Text="{Binding Status, Converter={StaticResource PostStatusConverter}}" FontFamily="Segoe UI Symbol" FontSize="14" HorizontalAlignment="Right" VerticalAlignment="Center"/>
                                </Grid>
    
                                <!-- used for tapped anywhere on title and attribution -->
                                <Rectangle x:Name="rect_Header" Grid.RowSpan="2" Fill="Transparent"/>
    
                                <TextBlock x:Name="tb_Summary" Grid.Row="2" Margin="0,5" TextTrimming="CharacterEllipsis" MaxLines="4" FontSize="20" FontFamily="Segoe WP" Foreground="{ThemeResource CNBlogsSummaryColor}" TextWrapping="Wrap" Visibility="Collapsed">
                                    <Run Text="{Binding Summary}"/>
                                    <Run Text="..."/>
                                    <TextBlock.Resources>
                                        <Storyboard x:Name="sb_Summary">
                                            <DoubleAnimation Storyboard.TargetName="tb_Summary" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:1"/>
                                        </Storyboard>
                                    </TextBlock.Resources>
                                </TextBlock>
                                <local:AttributionControl x:Name="control_Attribution" Grid.Row="3" HorizontalAlignment="Right" Visibility="{TemplateBinding AttributionVisible}" FontFamily="Global User Interface"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    我就想知道,上面的数据绑定绑定到哪了?即使是先写好了数据模型,里面有 TitlePublicTime 等属性,但那些 {Binding Title}{Binding PublicTime} 是怎么访问到 TitlePublicTime 的?




    2015年10月24日 13:43

答案

  • 楼主,对于这种情况,可以有多种实现方式,其中一种实现方式就是为其添加依赖属性,然后在使用中绑定对应的依赖属性即可!希望我的解答对您有所帮助,谢谢!
    2015年10月24日 14:02
  • 嘿,我知道了!可能是我 IDE 的问题!!!

    这里其实是不需要设置数据上下文的(Page 的 XAML 里设置,而不需要自定义控件里设置哦),运行时自动去寻找这些绑定的成员,我之前 IDE 应该有问题,居然会在 绑定的成员 下显示下划线说找不到。==

    这里的 TitlePublicTime 等属性 和你以后的 数据上下文 的类型里的成员同名即可,可以说 TitlePublicTime 等属性只是占位符而已。


    2015年10月26日 7:28

全部回复

  • 楼主,对于这种情况,可以有多种实现方式,其中一种实现方式就是为其添加依赖属性,然后在使用中绑定对应的依赖属性即可!希望我的解答对您有所帮助,谢谢!
    2015年10月24日 14:02
  • 但他这个不是通过依赖属性实现的(有一个是,大部分不是)
    2015年10月24日 14:33
  • 你去查看下PostControl的DataContext,DataContext里肯定是有Title,PublicTime等这些属性的。
    2015年10月26日 1:23
  • 看了下 PostControl 的构造函数涉及到

    public PostControl()
    {
                this.DefaultStyleKey = typeof(PostControl);
                this.DataContextChanged += PostControl_DataContextChanged;
    }


    void PostControl_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
    {
                this.UpdateUI(false);
    }


    private void UpdateUI(bool showAnimation = true)
    {
                CNBlogs.DataHelper.DataModel.Post post = this.DataContext as CNBlogs.DataHelper.DataModel.Post;
                if (post == null)
                {
                    return;
                }
    
                switch (post.Status)
                {
                    //略。
                }
    }

    但还有一点感到奇怪,这里为什么是:

    CNBlogs.DataHelper.DataModel.Post post = this.DataContext as CNBlogs.DataHelper.DataModel.Post;

    this.DataContext 转型为 Post ,这岂不是 PostContext 已经有 DataContext 了?也就是说在此之前,this.DataContext 已经被设置为 Post(具体 Page CodeBehind 设置),难道这样写就能解决我说问的问题???

    按理说这是自定义控件,只是定义一个模板,PostControl 的构造函数中应该直接设置(只少初始化一个)DataContext 才能访问,这个 DataContextChange 只是响应 DataContext 的更改,对于 DataContext 具体是什么只有更改了才知道啊,这是在运行时得知的而不是现在的设计时啊,设计时不直接设置 DataContext 怎么可能访问的到???



    2015年10月26日 2:14
  • 嘿,我知道了!可能是我 IDE 的问题!!!

    这里其实是不需要设置数据上下文的(Page 的 XAML 里设置,而不需要自定义控件里设置哦),运行时自动去寻找这些绑定的成员,我之前 IDE 应该有问题,居然会在 绑定的成员 下显示下划线说找不到。==

    这里的 TitlePublicTime 等属性 和你以后的 数据上下文 的类型里的成员同名即可,可以说 TitlePublicTime 等属性只是占位符而已。


    2015年10月26日 7:28