【发布时间】:2016-01-06 18:08:25
【问题描述】:
如果我有这个:
<Grid xmlns:local="clr-namespace:xaml_collections">
<StackPanel>
<StackPanel.DataContext>
<local:AComposite>
<local:AComposite.TheChildren>
<Rectangle
Height="85"
Width="85"
Fill="Red"
x:Name="foobar"
/>
</local:AComposite.TheChildren>
</local:AComposite>
</StackPanel.DataContext>
<TextBlock DataContext="{Binding TheChildren[0]}">
<Run Text="{Binding Height}"></Run>
</TextBlock>
<TextBlock DataContext="{Binding ChildrenByName[foobar]}">
<Run Text="{Binding Height}"></Run>
</TextBlock>
</StackPanel>
</Grid>
还有这个:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Shapes;
using System.Collections.Specialized;
namespace xaml_collections
{
public class AComposite : FrameworkElement
{
public AComposite()
{
if (_TheChildren != null && _TheChildren is ObservableCollection<Rectangle>)
{
((ObservableCollection<Rectangle>)_TheChildren)
.CollectionChanged += AComposite_CollectionChanged;
}
}
void AComposite_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e != null && e.Action == NotifyCollectionChangedAction.Add && e.NewItems != null)
{
foreach (var anItem in e.NewItems)
{
if (anItem is FrameworkElement)
{
FrameworkElement theFrameworkElementItem = (FrameworkElement)anItem;
_ChildrenByName.Add(theFrameworkElementItem.Name, theFrameworkElementItem);
}
}
}
}
private Dictionary<String,FrameworkElement> _ChildrenByName = new Dictionary<String,FrameworkElement>();
public Dictionary<String,FrameworkElement> ChildrenByName
{
get
{
return _ChildrenByName;
}
private set { }
}
private IList _TheChildren = new ObservableCollection<Rectangle>();
public IList TheChildren
{
get
{
return _TheChildren;
}
private set { }
}
}
}
我可以在设计时看到绑定到Children[0] 的TextBlock 的TextBlock 中的Height 值为85。但我只能看到ChildrenByName[foobar] 的值。运行时的高度。有没有办法在设计时保持这些集合同步?
编辑
这似乎有效,感谢尼克米勒。这里的教训是假设不要尝试创建衍生集合。使用不复制集合的属性,而只是引用它。
public Dictionary<String,FrameworkElement> ByName
{
get
{
return
this.Children.AsQueryable().Cast<FrameworkElement>()
.ToDictionary( element => element.Tag.ToString() );
}
}
还有这样的事情:
public List<FrameworkElement> Top3
{
get
{
return
this.Children.AsQueryable().Cast<FramworkElement>().
OrderByDescending( element => element.Height )
.Take(3).ToList();
}
}
【问题讨论】:
-
如果您添加带有虚拟数据的设计时视图模型,它将允许您查看 UI 在“真实世界”情况下的外观
-
@d.moncada 为什么我需要它?至少在一种情况下,我已经可以看到在 TheChildren 中初始化的“虚拟”数据。如果没有必要,我不希望有更多的“虚拟”东西四处飘荡。
-
请问你为什么从
FrameworkElement派生? -
@NickMiller 好问题。我不完全确定,但基本上我希望能够使用 XAML 来创建这些类型的数据上下文,这似乎很自然,而不是,什么可能......更合适——DependencyObject?如果有意义的话,我还有一些未来的目标,即为 DataContexts AND 视觉表示使用相同的类层次结构。
-
我问的原因是
DataContext通常是模型/视图模型的一部分,而不是应用程序的视图。您的AComposite课程到底应该是什么?它应该是某种视觉元素的容器吗?