Data binding DataContext和GridView/ListView的陌生性

Data binding DataContext和GridView/ListView的陌生性,data-binding,windows-8,windows-runtime,windows-store-apps,Data Binding,Windows 8,Windows Runtime,Windows Store Apps,我有一个基于分组模板项目的Windows 8应用商店应用程序,有一些重命名等。但是,我很难让ItemsSource数据绑定在未捕捉和捕捉的视觉状态下工作 我有一个属性,该属性在设置时会更改ItemsSource属性,但我一次只能绑定一个控件(对于未捕捉的控件,可以是GridView,对于捕捉的控件,可以是ListView) 当我使用以下内容时,只有未捕捉的绑定工作,捕捉的绑定不显示任何项目: protected PickLeafModel ListViewModel { get {

我有一个基于分组模板项目的Windows 8应用商店应用程序,有一些重命名等。但是,我很难让ItemsSource数据绑定在未捕捉和捕捉的视觉状态下工作

我有一个属性,该属性在设置时会更改ItemsSource属性,但我一次只能绑定一个控件(对于未捕捉的控件,可以是GridView,对于捕捉的控件,可以是ListView)

当我使用以下内容时,只有未捕捉的绑定工作,捕捉的绑定不显示任何项目:

protected PickLeafModel ListViewModel
{
  get
  {
    return (PickLeafModel)m_itemGridView.ItemsSource;
  }

  set
  {
    m_itemGridView.ItemsSource = value;
    m_snappedListView.ItemsSource = value;
  }
}
如果我注释掉其中一个设置器,则捕捉视图显示项目,而非捕捉视图不显示任何内容:

protected PickLeafModel ListViewModel
{
  get
  {
    return (PickLeafModel)m_itemGridView.ItemsSource;
  }

  set
  {
    //m_itemGridView.ItemsSource = value;
    m_snappedListView.ItemsSource = value;
  }
}
这就好像我一次只能将视图模型绑定到一个属性。我做错了什么

因为我正在另一个线程上生成数据模型(是的,使用线程池),所以我不能让它从DependencyObject继承。如果我这样做,我会得到一个错误的例外

因此,为了使其发挥作用,我做了以下工作:

public class PickLeafModel : IEnumerable
{
  public PickLeafModel()
  {
  }

  public IEnumerator GetEnumerator()
  {
    if (m_enumerator == null)
    {
      m_enumerator = new PickLeafModelViewDataEnumerator(m_data, m_parentLeaf);
    }

    return m_enumerator;
  }

  private SerializableLinkedList<PickLeaf> m_data = 
    new SerializableLinkedList<PickLeaf>();
}
公共类模型:IEnumerable
{
公共模型()
{
}
公共IEnumerator GetEnumerator()
{
if(m_枚举数==null)
{
m_enumerator=新的PickLeafModelViewDataEnumerator(m_数据,m_parentLeaf);
}
返回m_枚举数;
}
私有SerializableLinkedList m_数据=
新的SerializableLinkedList();
}
然后我的物品看起来像这样:

  // Augments pick leafs by returning them wrapped with PickLeafViewData.
  class PickLeafModelViewDataEnumerator : IEnumerator
  {
    public PickLeafModelViewDataEnumerator(
      SerializableLinkedList<PickLeaf> data, PickLeaf parentLeaf)
    {
      m_viewDataList =
        new System.Collections.Generic.LinkedList<PickLeafViewData>();

      foreach (PickLeaf leaf in data)
      {
        PickLeafViewData viewData = new PickLeafViewData();
        viewData.copyFromPickLeaf(leaf, parentLeaf);
        m_viewDataList.AddLast(viewData);
      }

      m_enumerator = m_viewDataList.GetEnumerator();
    }

    public void Dispose()
    {
      m_viewDataList = null;
      m_enumerator = null;
    }

    public object Current
    {
      get
      {
        return m_enumerator.Current;
      }
    }

    public bool MoveNext()
    {
      return m_enumerator.MoveNext();
    }

    public void Reset()
    {
      m_enumerator.Reset();
    }

    private IEnumerator<PickLeafViewData> m_enumerator = null;

    private System.Collections.Generic.LinkedList<PickLeafViewData>
      m_viewDataList;
  }
}
//通过返回用PickLeafViewData包装的拾取叶来增加拾取叶。
类PickerAfModelViewDataEnumerator:IEnumerator
{
公共模型视图数据枚举器(
SerializableLinkedList数据,PickLeaf parentLeaf)
{
m_viewDataList=
新建System.Collections.Generic.LinkedList();
foreach(数据中的PickLeaf叶)
{
PickLeafViewData viewData=新的PickLeafViewData();
copyFromPickLeaf(叶,父叶);
m_viewDataList.AddLast(viewData);
}
m_enumerator=m_viewDataList.GetEnumerator();
}
公共空间处置()
{
m_viewDataList=null;
m_枚举数=null;
}
公共对象流
{
得到
{
返回m_enumerator.Current;
}
}
公共图书馆
{
返回m_枚举数。MoveNext();
}
公共无效重置()
{
m_枚举数.Reset();
}
私有IEnumerator m_枚举器=null;
private System.Collections.Generic.LinkedList
m_viewDataList;
}
}
有没有什么我根本做错了

谢谢你的帮助


谢谢

谢天谢地,有一种更简单的方法来做你正在尝试的事情

创建名为ViewModel的类,如下所示:

public class DataViewModel
{
    public DataViewModel()
    {
        Data = new ObservableCollection<PickLeafViewData>(new PickLeafModelViewDataEnumerator(m_data, m_parentLeaf));             
    }

    public ObservableCollection<PickLeafViewData> Data
    {
        get;
        set;
    }

}

这对你来说应该很有用。

谢天谢地,有一种更简单的方法来做你正在尝试的事情

创建名为ViewModel的类,如下所示:

public class DataViewModel
{
    public DataViewModel()
    {
        Data = new ObservableCollection<PickLeafViewData>(new PickLeafModelViewDataEnumerator(m_data, m_parentLeaf));             
    }

    public ObservableCollection<PickLeafViewData> Data
    {
        get;
        set;
    }

}

这对你来说应该很有效。

谢谢罗斯为我指明了正确的方向

我对这个解决方案不是100%满意,但它确实有效。基本上,我的想法是,在从工作线程获得PickLeafModel之后,我将其内部数据移植到类的派生版本中,该类支持数据绑定

public class PickLeafViewModel : PickLeafModel, IEnumerable
{
  public PickLeafViewModel()
  {
  }

  public PickLeafViewModel(PickLeafModel model)
  {
    SetData(model);
  }

  public void SetData(PickLeafModel model)
  {
    model.swap(this);
  }

  public IEnumerator GetEnumerator()
  {
    if (m_observableData == null)
    {
      m_observableData = new ObservableCollection<PickLeafViewData>();

      var data = getData();
      PickLeaf parentLeaf = getParentLeaf();
      foreach (PickLeaf leaf in data)
      {
        PickLeafViewData viewData = new PickLeafViewData();
        viewData.copyFromPickLeaf(leaf, parentLeaf);
        m_observableData.Add(viewData);
      }
    }

    return m_observableData.GetEnumerator();
  }
每当我想设置ListViewModel时,我都可以这样做:

  ListViewModel = new PickLeafViewModel(model); 
交换看起来像:

private static void swap<T>(ref T lhs, ref T rhs)
{
  T temp;
  temp = lhs;
  lhs = rhs;
  rhs = temp;
}

// Swaps internals with the other model.
public void swap(PickLeafModel other)
{
  swap(ref m_data, ref other.m_data);
  ...
private静态无效交换(ref T lhs,ref T rhs)
{
温度;
温度=lhs;
lhs=rhs;
rhs=温度;
}
//将内部构件与其他模型交换。
公共无效掉期(其他)
{
交换(参考m_数据,参考其他m_数据);
...

另外,PickerafModelViewDataEnumerator可以被完全删除。

感谢Ross为我指明了正确的方向

我对这个解决方案不是百分之百满意,但它确实有效。基本上,我的想法是,在我从工作线程获得PickLeafModel后,我将其内部数据移植到类的派生版本中,该类支持数据绑定

public class PickLeafViewModel : PickLeafModel, IEnumerable
{
  public PickLeafViewModel()
  {
  }

  public PickLeafViewModel(PickLeafModel model)
  {
    SetData(model);
  }

  public void SetData(PickLeafModel model)
  {
    model.swap(this);
  }

  public IEnumerator GetEnumerator()
  {
    if (m_observableData == null)
    {
      m_observableData = new ObservableCollection<PickLeafViewData>();

      var data = getData();
      PickLeaf parentLeaf = getParentLeaf();
      foreach (PickLeaf leaf in data)
      {
        PickLeafViewData viewData = new PickLeafViewData();
        viewData.copyFromPickLeaf(leaf, parentLeaf);
        m_observableData.Add(viewData);
      }
    }

    return m_observableData.GetEnumerator();
  }
每当我想设置ListViewModel时,我都可以这样做:

  ListViewModel = new PickLeafViewModel(model); 
交换看起来像:

private static void swap<T>(ref T lhs, ref T rhs)
{
  T temp;
  temp = lhs;
  lhs = rhs;
  rhs = temp;
}

// Swaps internals with the other model.
public void swap(PickLeafModel other)
{
  swap(ref m_data, ref other.m_data);
  ...
private静态无效交换(ref T lhs,ref T rhs)
{
温度;
温度=lhs;
lhs=rhs;
rhs=温度;
}
//将内部构件与其他模型交换。
公共无效掉期(其他)
{
交换(参考m_数据,参考其他m_数据);
...

另外,PickLeafModelViewDataEnumerator可以完全删除。

感谢Ross的回答。不幸的是,它不能“开箱即用”(抱怨我需要的是IEnumerable而不是IEnumerator)。这对我来说也太复杂了,无法准确理解您的解决方案。您能解释一下吗?谢谢Ross的回答。不幸的是,它无法“开箱即用”(抱怨我需要的是IEnumerable而不是IEnumerator)。这对我来说也太复杂了,无法确切理解您的解决方案试图做什么。您能解释一下吗?