Data binding DataContext和GridView/ListView的陌生性
我有一个基于分组模板项目的Windows 8应用商店应用程序,有一些重命名等。但是,我很难让ItemsSource数据绑定在未捕捉和捕捉的视觉状态下工作 我有一个属性,该属性在设置时会更改ItemsSource属性,但我一次只能绑定一个控件(对于未捕捉的控件,可以是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 {
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)。这对我来说也太复杂了,无法确切理解您的解决方案试图做什么。您能解释一下吗?