一个列表框项目范围内的命令绑定到一个属性上的视图模型父 [英] binding a command inside a listbox item to a property on the viewmodel parent

查看:123
本文介绍了一个列表框项目范围内的命令绑定到一个属性上的视图模型父的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直工作在这约一个小时,看着都那么相关的问题。

我的问题很简单:

我有HomePageVieModel:

  HomePageVieModel
+的IList< NewsItem> AllNewsItems
+ ICommand的OpenNews

我的标记:

 <窗​​口的DataContext ={结合HomePageViewModel ../& GT;
< ListBox中的ItemsSource ={绑定路径= AllNewsItems}>
 < ListBox.ItemTemplate>
   <&DataTemplate的GT;
       <&StackPanel的GT;
        <&的TextBlock GT;
           <超链接命令={绑定路径= OpenNews}>
               < TextBlock的文本={绑定路径= NewsContent}/>
           < /超链接>
        < / TextBlock的>
      < / StackPanel的>
    < / DataTemplate中>
< /ListBox.ItemTemplate>

该列表显示细跟所有的项目,但对我的生活无论我尝试的命令将不起作用:

 <超链接命令={绑定路径= OpenNewsItem,的RelativeSource = {的RelativeSource AncestorType = VM:HomePageViewModel,AncestorLevel = 1}>
<超链接命令={绑定路径= OpenNewsItem,的RelativeSource = {的RelativeSource AncestorType = VM:HomePageViewModel,**模式= FindAncestor}} **>
<超链接命令={绑定路径= OpenNewsItem,的RelativeSource = {的RelativeSource AncestorType = VM:HomePageViewModel,**模式= TemplatedParent}} **>

我总是得到:

System.Windows.Data错误:4:无法为参考结合查找源.....

更新
我设置我的ViewModel这样吗?没想到这会事:

 < Window.DataContext>
        <绑定路径=主页来源={StaticResource的定位}/>
    < /Window.DataContext>

我用的是ViewModelLocator类从MVVMLight工具包,它确实神奇。


解决方案

有两大问题开展工作,对你在这里。

的DataContext 的DataTemplate 设置为模板显示的项目。这意味着你不能只使用绑定不设置源。

另一个问题是,模板是指项目在技术上并不逻辑树的一部分,所以你不能搜索超过的DataTemplate 节点的祖先。

要解决这个问题,你需要有逻辑树外的约束力范围。您可以使用DataContextSpy定义这里

 < ListBox中的ItemsSource ={绑定路径= AllNewsItems}>
    < ListBox.Resources>
        < L:DataContextSpy X:键=dataContextSpy/>
    < /ListBox.Resources>    < ListBox.ItemTemplate>
        <&DataTemplate的GT;
            <&StackPanel的GT;
                <&的TextBlock GT;
                   <超链接命令={绑定源= {StaticResource的dataContextSpy},路径= DataContext.OpenNews}CommandParameter ={结合}>
                       < TextBlock的文本={绑定路径= NewsContent}/>
                   < /超链接>
               < / TextBlock的>
           < / StackPanel的>
       < / DataTemplate中>
   < /ListBox.ItemTemplate>
< /列表框>

I've been working on this for about an hour and looked at all related SO questions.

My problem is very simple:

I have HomePageVieModel:

HomePageVieModel
+IList<NewsItem> AllNewsItems
+ICommand OpenNews

My markup:

<Window DataContext="{Binding HomePageViewModel../>
<ListBox ItemsSource="{Binding Path=AllNewsItems}">
 <ListBox.ItemTemplate>
   <DataTemplate>
       <StackPanel>
        <TextBlock>
           <Hyperlink Command="{Binding Path=OpenNews}">
               <TextBlock Text="{Binding Path=NewsContent}" />
           </Hyperlink>
        </TextBlock>
      </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>

The list shows fine with all the items, but for the life of me whatever I try for the Command won't work:

<Hyperlink Command="{Binding Path=OpenNewsItem, RelativeSource={RelativeSource AncestorType=vm:HomePageViewModel, AncestorLevel=1}}">
<Hyperlink Command="{Binding Path=OpenNewsItem, RelativeSource={RelativeSource AncestorType=vm:HomePageViewModel,**Mode=FindAncestor}**}">
<Hyperlink Command="{Binding Path=OpenNewsItem, RelativeSource={RelativeSource AncestorType=vm:HomePageViewModel,**Mode=TemplatedParent}**}">

I just always get :

System.Windows.Data Error: 4 : Cannot find source for binding with reference .....

Update I am setting my ViewModel like this? Didn't think this would matter:

 <Window.DataContext>
        <Binding Path="HomePage" Source="{StaticResource Locator}"/>
    </Window.DataContext>

I use the ViewModelLocator class from the MVVMLight toolkit which does the magic.

解决方案

There's two issue working against you here.

The DataContext for the DataTemplate is set to the item the template is displaying. This means you can't just use binding without setting a source.

The other issue is that the template means the item is not technically part of the logical tree, so you can't search for ancestors beyond the DataTemplate node.

To solve this you need to have the binding reach outside the logical tree. You can use a DataContextSpy defined here.

<ListBox ItemsSource="{Binding Path=AllNewsItems}">
    <ListBox.Resources>
        <l:DataContextSpy x:Key="dataContextSpy" />
    </ListBox.Resources>

    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock>
                   <Hyperlink Command="{Binding Source={StaticResource dataContextSpy}, Path=DataContext.OpenNews}" CommandParameter="{Binding}">
                       <TextBlock Text="{Binding Path=NewsContent}" />
                   </Hyperlink>
               </TextBlock>
           </StackPanel>
       </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

这篇关于一个列表框项目范围内的命令绑定到一个属性上的视图模型父的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆