【问题标题】:WPF DataBinding with RelativeSource problemWPF DataBinding 与 RelativeSource 问题
【发布时间】:2011-07-01 13:46:57
【问题描述】:

我正在尝试创建一个包含 ListBox 的视图,该 ListBox 的 ItemsSource 属性绑定到 ObservableCollection 并且其 ItemTemplate 属性绑定到另一个属性。我知道不清楚,所以我会添加一些代码......

此代码是我的标记中的相关部分:

<ListBox ItemsSource="{Binding MyCollection}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding FirstName}" Height="{Binding Path=Index, RelativeSource={RelativeSource AncestorType={x:Type local:MainWindowViewModel}}}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

('FirstName'是Person类型的一个属性,是我的集合的类型参数,这个类的代码我就不加了,因为很直观) 视图的代码隐藏设置 DataContext 来保存对这个 ViewModel 类的引用和实例:

public class MainWindowViewModel : INotifyPropertyChanged
{
    int index;
    ObservableCollection<Person> myCollection;

    public ObservableCollection<Person> MyCollection
    {
        get 
        {
            if (myCollection == null)
            {
                //create the collection - not relevant for my question
            }
            return myCollection;
        }
    }
    public int Index
    {
        get
        {
            //calculate value...
        }
        set
        {
            //set the value...
        }
    }

由于我将 ItemsSource 绑定到集合,我发现很难绑定到 ViewModel 中的属性(我设法简单地绑定 Person 的属性...),并且我的代码在输出窗口中出现绑定错误:

找不到与引用“RelativeSource FindAncestor, AncestorType='SimpleMVVM.MainWindowViewModel', AncestorLevel='1'' 进行绑定的源。绑定表达式:路径=索引;数据项=空;目标元素是 'Button' (Name='');目标属性是“高度”(类型“双”)

有人可以帮我解决这个问题吗? (顺便说一句 - 抱歉标题不好,我只是找不到更清晰的内容)

【问题讨论】:

    标签: wpf data-binding mvvm


    【解决方案1】:

    您需要将高度绑定到视图模型的 DataContext 设置为现在它正在寻找集合中各个数据项的索引属性的方式

    【讨论】:

      【解决方案2】:

      Index 属性将位于 ListBox DataContext 中,因此将高度绑定更改为以下内容,它应该可以工作

      Height="{Binding Path=DataContext.Index,
                       RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"/>
      

      对于列表框

      <ListBox ItemsSource="{Binding MyCollection}">
          <ListBox.ItemTemplate>
              <DataTemplate>
                  <Button Content="{Binding FirstName}"
                          Height="{Binding Path=DataContext.Index,
                                           RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"/>  
              </DataTemplate>
          </ListBox.ItemTemplate>
      </ListBox>
      

      【讨论】:

      • 首先感谢您的回答。是的 - 你是对的,它就是这样工作的。我仍然很难理解为什么:假设 Index 属性位于 ListBox DataContext 中,这是有道理的。但为什么?它不应该位于Window DataContext中吗???再次感谢:)
      • @ET:这取决于,如果您为Window 设置DataContext,它将为Window 设置,然后它将被Window s Child 继承,除非该 Child以其他方式设置其 DataContext 。如果那个孩子是Panel,例如Grid,那么Grid 的所有Children 也将继承相同的DataContext。因此,DataContext 将一直继承到绑定到 DataContext 的MyCollection 属性的ListBox。所有ListBoxItem 容器都将有一个Collection 类型的实例作为DataContext。希望这回答了你的问题:)
      • 好的。在您的澄清和简短调查之后,我注意到 DataContext 属性是一个依赖属性,因此它具有值继承。现在一切都清楚了。再次感谢您的回答(和耐心......):)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-26
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多