none
WP8.1 的数据绑定有优先级和覆盖的概念吗?为什么我的数据绑定会无效? RRS feed

  • 问题

  • WP8.1 中心应用的模板中,HubPage.xaml 中有以下一行数据绑定代码:

    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    

    如果我的应用的 5 个 HubSection 中有一个不适用 DefaultViewModel 这个视图模型,我需要自定义一个 MyViewModel 视图模型,于是我在其中一个 HubSection 中使用了自定义的数据绑定代码:

    <HubSection x:Uid="HubSection1"
                Header="home"
                DataContext={Binding MyViewModel}
                HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}">
                <!--略:这里使用了 MyViewModel 的 代理属性。-->
    </HubSection>
    

    但我发现这个 HubSection 的数据绑定是无效的,只有使用后台代码绑定才有效!

    这个问题要如何解决?我希望数据绑定在 xaml 中完成。

    2015年3月5日 9:23

答案

  • Hello:

    数据绑定有向下延伸和覆盖的概念:

    首先说明一下绑定的原理:

    假设用CS代码绑定TextBlock控件的Text值为VM中的Name属性,则写法如下:

    Binding binding=new Binding();

    binding.Source=VM;

    Bindng.Path="Name";

    textBlock.SetBinding(TextBlock.TextProperty,binding);

    通过对这段CS代码的分析可以看出Binding有两个主要属性:

    1,Source:指定当前要绑定的“数据源对象”。

    2,Path:指定要绑定的某个属性值。

    如果你要绑定的TextBlock的Text值就是VM这个对象,则应该按照下面这种写法:

    Binding binding=new Binding();

    binding.Source=VM;

    textBlock.SetBinding(TextBlock.TextProperty,binding);

    再来看下你的问题:

    你的xaml布局结构是Hub里面包含一个HubSection,

    绑定方式为DataContext="{Binding DefaultViewModel,RelativeSource={RelativeSource Self}}"表示Hub的DataContext属性的值绑定的是页面本身cs文件中的DefaultViewModel属性。这时候Hub的Binding的Source为后台cs文件(当前Page的DataContext属性),而DefaultViewModel只是绑定的Path属性值。

    上面说的数据绑定有向下延伸和覆盖的概念,也就是说你在HubSection中写DataContext={Binding MyViewModel},表示HubSection的绑定源(Source)是DefaultViewModel,而Path的值是DefaultViewModel下面的MyViewModel属性,很明显DefaultViewModel下面没有MyViewModel属性。你实际想将HubSectionr的DataContext绑定到cs文件中的MyViewModel属性,这时候就用到了绑定的覆盖,你应该这样给HubSection绑定值:DataContext={Binding ElementName=rootPage,Path=DataContext.MyViewModel}(rootPage为当前页面的Name),表示你的HubSection的DataContext的绑定值是当前页面的绑定源中的MyViewModel属性。


    2015年3月18日 16:58

全部回复

  • 应该有的吧,你可以把你的代码都发过来测试看看
    2015年3月18日 6:58
  • Hello:

    数据绑定有向下延伸和覆盖的概念:

    首先说明一下绑定的原理:

    假设用CS代码绑定TextBlock控件的Text值为VM中的Name属性,则写法如下:

    Binding binding=new Binding();

    binding.Source=VM;

    Bindng.Path="Name";

    textBlock.SetBinding(TextBlock.TextProperty,binding);

    通过对这段CS代码的分析可以看出Binding有两个主要属性:

    1,Source:指定当前要绑定的“数据源对象”。

    2,Path:指定要绑定的某个属性值。

    如果你要绑定的TextBlock的Text值就是VM这个对象,则应该按照下面这种写法:

    Binding binding=new Binding();

    binding.Source=VM;

    textBlock.SetBinding(TextBlock.TextProperty,binding);

    再来看下你的问题:

    你的xaml布局结构是Hub里面包含一个HubSection,

    绑定方式为DataContext="{Binding DefaultViewModel,RelativeSource={RelativeSource Self}}"表示Hub的DataContext属性的值绑定的是页面本身cs文件中的DefaultViewModel属性。这时候Hub的Binding的Source为后台cs文件(当前Page的DataContext属性),而DefaultViewModel只是绑定的Path属性值。

    上面说的数据绑定有向下延伸和覆盖的概念,也就是说你在HubSection中写DataContext={Binding MyViewModel},表示HubSection的绑定源(Source)是DefaultViewModel,而Path的值是DefaultViewModel下面的MyViewModel属性,很明显DefaultViewModel下面没有MyViewModel属性。你实际想将HubSectionr的DataContext绑定到cs文件中的MyViewModel属性,这时候就用到了绑定的覆盖,你应该这样给HubSection绑定值:DataContext={Binding ElementName=rootPage,Path=DataContext.MyViewModel}(rootPage为当前页面的Name),表示你的HubSection的DataContext的绑定值是当前页面的绑定源中的MyViewModel属性。


    2015年3月18日 16:58