我有一个基于分组模板项目的Windows 8商店应用程序,有一些重命名等。但是,我很难让ItemsSource数据绑定工作两个非snapped并拍摄视觉状态。
我有一个属性,设置后会更改ItemsSource属性,但我一次只能获得一个要绑定的控件(GridView用于非snapped,或者ListView用于snapped)。
当我使用以下内容时,只有非捕捉的绑定有效,而捕捉的绑定不显示任何项目:
protected PickLeafModel ListViewModel
{
get
{
return (PickLeafModel)m_itemGridView.ItemsSource;
}
set
{
m_itemGridView.ItemsSource = value;
m_snappedListView.ItemsSource = value;
}
}
如果我注释掉其中一个setter,则捕捉的视图会显示项目,但非捕捉的视图不会显示任何内容:
protected PickLeafModel ListViewModel
{
get
{
return (PickLeafModel)m_itemGridView.ItemsSource;
}
set
{
//m_itemGridView.ItemsSource = value;
m_snappedListView.ItemsSource = value;
}
}
就好像我一次只能将我的视图模型绑定到一个属性。我做错了什么?
由于我在另一个线程上生成我的数据模型(是的,使用线程池),我不能让它继承自DependencyObject。如果我这样做,我会得到一个WrongThreadException。
为了使其成功,我做了以下工作:
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>();
}
然后我的项目看起来像这样:
// 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;
}
}
我在做什么根本就错了吗?
帮助表示赞赏。
谢谢!
答案 0 :(得分:1)
值得庆幸的是,有一种更简单的方法来做你正在尝试的事情!
创建一个名为ViewModel的类,如下所示:
public class DataViewModel
{
public DataViewModel()
{
Data = new ObservableCollection<PickLeafViewData>(new PickLeafModelViewDataEnumerator(m_data, m_parentLeaf));
}
public ObservableCollection<PickLeafViewData> Data
{
get;
set;
}
}
现在在后面的代码中,将Page.DataConected设置为等于上述类的实例。
最后在你的快照列表视图上,网格视图将项目源设置为: -
ItemsSource="{Binding Data}"
这应该很适合你。
答案 1 :(得分:0)
感谢罗斯指出我正确的方向。
我对此解决方案并不十分满意,但确实有效。基本上我的想法是,在从工作线程返回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();
}
,页面代码如下:
protected PickLeafViewModel ListViewModel
{
get
{
return DataContext as PickLeafViewModel;
}
set
{
DataContext = value;
}
}
每当我想设置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);
...
此外,可以完全删除PickLeafModelViewDataEnumerator。